*Using join buffer:该值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果 。
*Impossible where:这个值强调了where语句会导致没有符合条件的行 。
*Select tables optimized away:这个值意味着仅通过使用索引,优化器可能仅从聚合函数结果中返回一行
*No tables used:Query语句中使用from dual 或不含任何from子句
以上就是对EXPLAIN工具的一个介绍,了解了这个工具后,我们结合这个执行工具,来看一看哪些情况会导致这个索引失效!
第一种情况:针对联合索引,是否遵循最左匹配原则;
我们user_name,user_password,mobile建立一个联合索引,如下:
文章插图
联合索引其实是建立了三个索引,也就是user_name的索引,user_name,user_password的索引,user_name,user_password,mobile的索引,最左匹配原则的意思,是否在语句中使用了最左建立的索引,也就是user_name的索引,演示一下:
文章插图
当我们把user_name的查询条件去掉之后,会是什么情况呢?
文章插图
我们会看到索引已经失效了,用的是全表扫描,违背了最左匹配的原则,那么对于查询语句select * from tb_user where user_password='admin66666' and user_name='admin66666' and mobile='1234566666'会用到索引吗?答案如下:
文章插图
也是用到了联合索引,这和你条件中写的顺序是没有关系的!
【MySQL索引失效和EXPLAIN工具:你建立的索引真的起到作用了吗?】第二种情况:在索引列上做了函数操作,会导致索引失效而导致全表扫描
我们先把那个联合索引删除掉,然后在user_name这一列上建立一个唯一索引:
文章插图
文章插图
文章插图
先不在索引列上做函数操作,执行计划如下:
文章插图
很显然使用了索引,那么索引列进行函数操作呢?例如做一个字符拼接的操作:
文章插图
第三种情况:语句中like查询是以%开头,索引会失效变成全表扫描,覆盖索引 。
示例如下:
文章插图
如果模糊查询不是以%开头的,那么也是可以用到索引的:
文章插图
第四种情况:使用is not null 会导致无法使用索引
示例如下:
文章插图
第五种情况:查询语句中,如果条件中有or,即使其中有条件带索引也不会使用 。要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引
文章插图
上面的sql语句是可以用到索引的,当我们把and换成or时,就会变成全表扫描:
文章插图
这时我们对mobile也加上索引,这条sql语句也就会使用上索引:
文章插图
文章插图
第六种情况:使用不等于(!= 或者<>)的时候,无法使用索引,会导致索引失效
第七种情况:不能使用索引中范围条件右边的列,范围之后索引失效 。(< ,> between and)
这些情况就不在进行实际操作了,感兴趣的朋友可以动手操作一下,也许随着MySQL版本的更新迭代,对这些查询语句进行内部优化,一些索引失效的情况就会消失 。除了以上这些情况会导致索引失效,还有哪些情况会导致索引失效呢?
推荐阅读
- MySQL如何选择合适的索引
- 详解MySQL数据恢复
- 淘宝搜索引擎排名规则 淘宝的搜索排名由什么决定的
- MySQL数据库性能优化之thread pool 原理分析,值得收藏
- 一篇全面的 MySQL 高性能优化实战总结
- Mysql视图
- MySQL索引的原理,B+树、聚集索引和二级索引的结构分析
- 超详细的mysql数据库主备切换演练教程,值得收藏
- mysql导入数据
- Centos7 下YUM安装 MySQL5.7