Mysql( InnoDB)索引失效场景

184 阅读2分钟

总结索引失效场景

先看一下b+树索引结构图

image.png

image.png

1. 对索引使用左模糊匹配

比如select * from t_user where name like ”%林“;

  1. 只要是第一个like后面的字符串第一个是%就走不了索引,会扫全表。
  2. 如果是"林%",可以通过“林”字段在索引里面找到一个范围再去范围查找。

2. 对索引使用函数

比如select * from t_user where length(name)=6;

  1. 这个很好理解,我们对name建立了索引,但是并没有对length(name)做索引,都没有这个索引那肯定失效。
  2. 再大白话讲一下,我们建立了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.对索引隐式类型转换

  1. select * from t_user where phone = 1300000001;

  2. 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中存在非索引列和索引列。