总结索引失效场景
先看一下b+树索引结构图
1. 对索引使用左模糊匹配
比如select * from t_user where name like ”%林“;
- 只要是第一个like后面的字符串第一个是%就走不了索引,会扫全表。
- 如果是"林%",可以通过“林”字段在索引里面找到一个范围再去范围查找。
2. 对索引使用函数
比如select * from t_user where length(name)=6;
- 这个很好理解,我们对name建立了索引,但是并没有对length(name)做索引,都没有这个索引那肯定失效。
- 再大白话讲一下,我们建立了name的B+树索引,去找数据可以通过name对应的值去比较,左边小右边大。但是如果是length(name),我们在name索引上是无法去比较的,除非建立一个length(name)的索引。
3. 对索引进行表达式计算
比如select * from t_user where id + 1 = 10;
和2一个道理,id存在索引,但是id+1是不存在索引的,自然就走不了索引。可以修改为id = 10 - 1就可以走索引了。
4.对索引隐式类型转换
select * from t_user where phone = 1300000001;
select * from t_user where id = "1";
- 这里我的phone字段是varchar类型,id是int类型。可以看到一个非常有意思的事情就是1不能走索引,2能走索引。
- 原因是数字和字符串比较的时候会把字符串转成数字然后再比较,那如果索引是字符串被转换了那就走不了索引。
5.联合索引非最左匹配
最左匹配原则:按照最左优先的方式进行索引的匹配。
比如我们现在联合索引为(a, b, c),下面这些能面中索引。
- where a=1;
- where a=1 and b=2 and c=3;
- where a=1 and b=2;
PS:a = 1的顺序无所谓,有查询优化器会堆sql做优化。
其实就是只要第一个匹配上了就会走索引,如果能按最左匹配原则匹配的越多,效率就会越高。
6.WHERE 子句中的 OR
比如select * from t_user where id = 1 or age = 18;
- 像这种是无法走索引的,因为age不是索引,如果要走索引只能把age也加上索引。
- or的语义是只要有一个满足就可以
总结 索引失效场景
- 使用左或者左模糊匹配的时候。
- 查询条件中对索引列使用函数。
- 查询条件中对索引列进行表达式计算。
- 字符串和数字比较,且索引列是字符串。
- 联合索引不遵循最左匹配原则。
- OR中存在非索引列和索引列。