【DataBase】关于索引相关问题的分析

前提

在开始之前先建立一个数据表,名为score,具体的字段以及相关的主键、索引设置如下:
在这里插入图片描述
在这里插入图片描述
添加一些数据:
在这里插入图片描述
接下来将使用EXPLAIN对SQL语句进行分析,关于生成的分析表中各字段的含义解释可以参考博客:MySQL使用explain时各字段解释;接下来就进入正题。

1、索引失效的情况

  • 查询条件条件中有or 关键字,且or连接的条件字段不是所有的都为索引列;SQL语句以及执行结果如下:
    在这里插入图片描述
  • 对于覆盖索引,需要遵循最左匹配原则,如果不遵循最左匹配原则,则会导致全表扫描,type=index本身是另外一种形式的全局扫描:
    在这里插入图片描述
  • 数据类型出现隐式转化时,会导致索引失效;如下所示,name为varchar类型,不加单引号默认为数字类型,所以会导致name字段的索引失效:
    在这里插入图片描述
  • where子句中的索引字段含有函数运算时,索引失效,执行全局索引扫描:
    在这里插入图片描述
  • 当全表扫描速度比索引速度快时,mysql会使用全表扫描,此时索引失效;
    例如数据量比较少的时候就容易出现这样的情况。

网上还有提到一种情况:LIke条件语句进行模糊匹配的时候,如果%在最左边则索引失效,但是我的测试结果是索引仍然适用,mysql版本5.7

推荐一篇关于EXPLAIN分析很到位的文章:MySQL 性能优化神器 Explain 使用分析

2、覆盖索引中的最左匹配原则

最左匹配原则是覆盖索引中一个比较重要的概念,如1中介绍的情况就有一种不满足最左匹配原则导致索引失效的,接下来介绍几种满足最左匹配的情况,还以上边使用的数据为例:

第一种:虽然name和score的位置反了,但是mysql的查询优化器仍然会找到最高效的执行顺序;
在这里插入图片描述
第二种:只使用最左侧的条件
在这里插入图片描述

如果说一个索引中包含更多个字段,如:(A,B,C…);如果where中没有B,则即使有C,字段C及其后边的列的索引也不生效。

3、覆盖索引中的索引下推

索引下推是MySQL5.6以后才有的新功能,在2中介绍了几种满足最左匹配原则的覆盖索引查询操作,我们之前介绍的所要查询的字段均为我们建立索引或者覆盖索引中包含的字段,如果我们查询的字段中包含一些非索引的列会怎样?我们来测试下:
在这里插入图片描述
在原来的条件中在添加一个所要查询的字段money,这是看下分析结果,Extra变为了Using index condition,这其实就是进行了索引下推的操作;在联合索引内部先根据score=3.22和name='历史’这两个条件来分析出对应数据行的id,然后在使用id取数据表中取数据,这样可以减少回表的次数。而在5.6以前的版本中,mysql会先忽略掉name='历史’这个条件,先在索引树中找到score=3.22的节点对应的表的id,然后拿着id去数据表中取数据,由于数据表中score=3.22的数据行可能不止一个,所以就会造成多次回表的情况。

参考博客:
1、覆盖索引、联合索引、索引下推
2、Mysql性能优化:什么是索引下推?
3、MySQL之 索引下推

猜你喜欢

转载自blog.csdn.net/qgnczmnmn/article/details/107838001