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