索引失效意味着 查询操作 不能利用索引进行数据检索,而是使用 全表扫描(也就是 数据库需要从磁盘上读取表的所有数据行),从而导致性能下降,下面一些场景会发生索引失效
-
对索引使用左或者左右模糊匹配(where name like ‘%林’)
- B+ 树是按照索引值 从左往右 有序排列存储的,所以需要从前面开始比较
- 如果使用 name like ‘%林’ 方式来查询,因为查询的结果可能是「陈林、张林、周林」等之类的,所以不知道从哪个索引值开始比较,于是就只能通过 全表扫描 的方式来查询
-
联合索引不满足最左匹配(where b=2 and c=3)
-
对 主键字段 建立的索引叫 聚簇索引,对 普通字段 建立的索引叫 二级索引。那么 多个普通字段 组合在一起创建的索引就叫做 联合索引
-
最左匹配原则,也就是按照 最左优先的方式进行索引的匹配。比如创建了一个
(a, b, c)
联合索引,在where条件中必须要带有 a字段的值。先按照a字段排序,a字段相同 才会按照b字段排序
-
-
WHERE 子句中的 OR
- 在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列只是普通列,而不是索引列,那么索引会失效。因为 OR 的含义就是 两个只要满足一个即可,只要有条件列不是索引列,就会进行全表扫描
-
对索引使用函数
-
索引 保存的是原始值,没法和函数计算后的值进行比较
-
不过,从 MySQL 8.0 开始,索引特性增加了 函数索引,也就是可以针对 函数计算后的值建立一个索引,该索引的值是函数计算后的值,所以 就可以通过扫描索引来查询数据
-
-
对索引进行表达式计算
- 索引保存的是索引字段的原始值,而不是 id + 1 表达式计算后的值,所以无法走索引
-
对索引 隐式类型转换(大转小)
- 需要分情况讨论:如果是转换索引,就相当于是 对索引使用函数,则索引失效;如果转换的是等号右边的值,则索引本身不变,此时索引不会失效
- 比如索引原来是字符串类型,而我们输入一个整形,这样的后果就是 索引会执行自动类型转换,也就是等效于对索引使用函数,使索引失效。如果索引是整形,而输入字符串,只会对输入的字符串进行自动类型转换,对索引本身不会任何改变,所有这样不会导致索引失效