MySQL存储引擎不能使用索引中范围条件右边的列

一、前言

对于range查询,在一条组合索引里面,range字段后面的列是不生效的,不会使用索引,range列自身仍是生效的。

二、正文

(1)首先建立一个学生表:

(2)建立一个联合索引(name,age,class_id)

测试

Case1:

只有 name 且是等于

explain select * from student where name = Mitsunari

结果如下:

注意:ken_len字段长度和ref字段使用了索引中的第一列,也就是name。

Case2:

name和age并且是等于

explain select * from student where name = Mitsunari and age = 44

结果如下:

注意:ken_len字段长度和ref字段使用了索引中的第一列和第二列,也就是name和age。

Case3:

name、age和class_id并且是等于

explain select * from student where name = Mitsunari and age = 44 and class_id = 2

结果如下:

注意:ken_len字段长度和ref字段使用了索引中的第一列和第二列和第三列,也就是name、age和class_id。

Case4:

name 是等于,age 不是等于(class_id其实已经使用不上索引了)

explain select * from student where name = Mitsunari and age > 44 and class_id = 2

结果如下:

下面分析下Case4:

(1)type是range,注意上面三条语句全是 type=ref,Case4是range,已经劣了一级。

(2)key_len=61,这个和Case2的长度相同,说明只有name和age两个索引生效,class_id没有用到索引。

(3)ref=null,前面全是const。

Case5:

只有age,age 不是等于(在age上建立一个单独的索引)

explain select * from student where age > 30

上面的语句执行explain之后,是否会走索引?

我们看下结果:

结果是没有走索引,是全表搜索。

是不是很意外,不对啊,你上面说range列自身仍是生效的,这怎么没走索引?

我们在看下这种情况:

explain select * from student where age > 44

会走索引嘛?

走了,走的是age这个单独索引,并且type=range。

为什么?

因为 >,<,>=,<=不一定走索引,因为优化器会计算,符合条件的值的总和,与总数据量的比值,比值<=0.30,才会走索引。具体情况就不分析了,可以看下这篇文章解释的很清楚:“”

当然上面这种情况只是针对where查询中只有一个字段做范围查询,要是Case4中那样,则会走联合索引的。

三、总结

范围查询后面的会失效—存储引擎不能使用索引中范围条件右边的列。

最后引用我很佩服的一个人经常说的话:你知道的越多,你不知道的越多!

https://blog..net/m0_45406092/article/details/112196476

经验分享 程序员 微信小程序 职场和发展