群里大佬聊天,组合索引里面a,b,c三个字段索引,在遵循最左匹配原则情况下,单独b,c是不走索引的。可是群里又有大佬提出了疑惑,说select * form table where b = 2 and c = 3; 是走索引的。

上图:

单建索引 和组合索引 组合索引单个会走吗_sql

从图中看出,确实bc是走了索引的。这是为什么呢?

我直接人都麻了,打破我以前理解的观点了啊。

随即,我就去创了个表,做了一番测试。

上图:

单建索引 和组合索引 组合索引单个会走吗_单建索引 和组合索引_02

从图中可以看出,我的语句跟索引与上图一模雕样,为啥他的走了索引,我的没走索引呢。

百思不得其解,突然打破我以前自己理解的观念,非常难受,我就上网百度了一番,看到了一篇文章,和我的结果也是一毛一样。

上图:

单建索引 和组合索引 组合索引单个会走吗_sql_03

 select*之下,where条件里联合索引走得是b,确实是没走索引,全表扫描了。

然后我就想,是不是字段的原因,分析一下:

EXPLAIN SELECT * from user where sex='女'; 我的select*字段有五个,联合索引是三个字段,我现在where条件里排列作何是单独b索引,正常情况下,先根据sex字段去sexB+树上找到对应的数据,然后从叶子结点获取到Value的值,根据Value的值再去idB+树中查询数据,返回最后的结果,这个过程就是回表。他也确实是没走索引

然后我就有点麻了,找了个摸鱼大师问了一句:

单建索引 和组合索引 组合索引单个会走吗_单建索引 和组合索引_04

我就去测试了一下,把没有建立索引的字段给删掉,一个username,一个password。验证大师的第一句话,select* 里面的字段名全都包含在where条件的联合索引里面。果不其然,确实走了索引。下图有展示:

 

单建索引 和组合索引 组合索引单个会走吗_数据库_05

 然后第二句话就是,select* 有字段名,在where条件里面的联合索引不包含,那就不走索引,也就验证了我第一次测的时候,不走索引,是因为有字段不在索引里面查不到,导致回表了。

也就是说:测试这个问题时候,创建表后,字段要超过组合索引字段的个数,不然所有字段要小于等于索引字段名的话,他会命中覆盖索引,只是他走的是index索引,但也符合索引的定义。

所以也就得出 我以下瞎总结的几句屁话:

总结:

1.select语句中,有字段名在联合索引里面不存在的情况下,是会导致回表,从而不走索引。(回表效率低,不推荐使用)

单建索引 和组合索引 组合索引单个会走吗_面试_06

2. select语句中,所有字段名都包含在where条件里下联合索引里面,是直接根据索引的值去索引字段的B+树上查找数据,找到数据之后,直接返回即可,不需要查询id的B+树,这个过程也叫作索引覆盖。也就是走了索引,下面图中也可以看出Explain计划里面Extra是走得using index。(索引覆盖效率高,推荐使用)

单建索引 和组合索引 组合索引单个会走吗_单建索引 和组合索引_07

emmm,只要是你条件满足了最左匹配原则,他是一定会走索引的。

你条件没有满足最左原则,但是你所以字段里面只包含联合索引或者主键,他走的是index索引,而不是你创建的索引,但是他也符合索引定义。

怕明天忘了,十几分钟写出来的,有啥不对的评论区指出来一下。