likes
comments
collection
share

花十分钟了解一下索引失效原理

作者站长头像
站长
· 阅读数 74

1:索引失效场景

  • 1.1:对索引做函数计算
  • 1.2:不符合最左前缀原则
  • 1.3:like使用不当
  • 等等

2:为什么索引会失效(单个索引)

在MySql底层当对索引字段做了函数操作那么就是不会走索引的,那么我们可以想下为什么MySql要这么做。当我们为name 创建了索引,就会为name创建一颗B+树。

当我们添加一条记录之后,就会获取name这个字段的值,然后进行相应的运算,最后得出一个值,最后拿这个值去这颗树做比较,最后找到一个位置放置该字段的值。

花十分钟了解一下索引失效原理

但是存储的结果从左到右都是从小到大排序的,如下图的叶子结点。如果你现在执行的SQL语句如下

mysql可以拿到该字段的值进行运算,得到最后的值可以直接在索引树中找到对应的值,此时是可以使用索引的
explain select * from user where name = 'canal';

但是如果是这样执行,我们对索引字段做了函数操作了,此时索引会失效,那是为什么呢??

explain select * from user where 大写转小写(name) = 'CANAL';

此时我们对字段做了函数操作,假设我们还是要使用索引,也就是还是要到索引树中去找,此时你还能利用索引的排序功能吗??肯定不能了,因为你肯定要对索引树每一个值进行该函数的操作然后再对比了

举个例子:假设有这么一些数据 [张三,李四,王五],此时你写了一个函数让他们拍好序了,此时你要找这里面是否有 張三,也就是张三的繁体,对于你排序函数来说張三就是一个新元素,你在原来的数据中是找不到的。但是此时你其实想找的就是张三只不过你找的是它的繁体而已。那你是不是要把原来的每一个元素都进行繁体的转换,然后再对比,是不是这样???

所以MySql认为你既然要每一个都进行函数然后再对比,那还不如直接让你进行全表扫描

3: 为什么索引会失效(联合索引)

假设我们现在有个联合索引name,age,那么此时该联合索引在底层排序是首先按照name字段进行排序,如果name相等,那么再按照age进行排序

花十分钟了解一下索引失效原理

3.1:为什么单独使用age是不会走索引

看下这课红黑树,如果我们单独使用age的话,那么age就是无序的,既然无序就自然不能使用树的特性(左节点小于右节点等等)来进行查找了 花十分钟了解一下索引失效原理

3.2 为什么联合索引有一个使用范围查询后面的索引就不能使用

还是这张图,假设我们现在对name进行范围查询,假设找到了 [李 12],[李 14],[李 56],[王 18],现在对于name字段是有序的,但是对于age字段就不是有序的了。

假设你现在Sql = where name = '李' and age = 14 是这样的,那么首先根据name字段找到 [李 12],[李 14],[李 56]这三条数据,联合索引当前面索引相等才会使用后面的一个索引来进行排序,此时name字段相等,所以age就是有序的,那么自然能使用树的特性来找,也就能使用索引了

3.3:使用like %name and age = 1 为什么age不能使用索引

其实 %like本质也就是范围查询了,既然name使用了范围查询,那么age自然就无序,也就不能使用索引了

4:总结

其实很多种索引失效的本质与上面一致,至于单个索引失效是MySql底层这样实现的,我只是猜测大概的想法,有错误欢迎指出,大家一起进步

转载自:https://juejin.cn/post/7044793268780924935
评论
请登录