# MySQL 索引失效
# 1. 隐式的类型转换,索引失效
MySQL会做隐式的类型转换,会导致索引会失效。常见的字符型字段传入数字
# 2. 查询条件包含 or,索引可能
失效
遇到不走索引的时候,考虑拆开两条SQL
# 3. like通配符可能导致索引失效
# 4. 查询条件不满足联合索引的最左匹配原则
MySQl建立联合索引时,会遵循最左前缀匹配的原则,即最左优先。如果你建立一个(a,b,c) 的联合索引,相当于建立了(a)、(a,b)、(a,b,c)三个索引。在联合索引中,查询条件满足最左匹配原则时,索引才正常生效。
# 5. 在索引列上使用mysql的内置函数
# 6. 对索引进行列运算(如,+、-、*、/),索引不生效
不可以对索引列进行运算,可以把运算放到右边或者直接在代码中处理好,再传参进去。
# 7. 索引字段上使用(!= 或者 < >),索引可能
失效
MySQL优化器觉得即使走索引,还是需要扫描很多行,它觉得不划算,不如直接不走索引。平时我们用!=
或者not in
的时候,需要注意
# 8. 索引字段上使用is null, is not null,索引可能
失效
很多时候是因为数据量的问题,导致MySQL优化器放弃走索引。我们平时用explain分析SQL的时候,如果type=range时要注意一下,因为这个可能因为数据量的问题,导致索引无效。
# 9. 左右连接,关联的字段编码格式不一样
字段编码有些是utf8mb4,有些为为utf8。大家在做表关联时,注意一下关联字段的编码问题
# 10. 优化器选错了索引
- 1)使用force index 强行选择某个索引
- 2)修改SQL,引导它使用我们期望的索引
- 3)优化业务逻辑,优化索引;新建一个更合适的索引,或者删除误用的索引
# MySQL 索引在 in 条件下失效的原因
首先我们看IN
索引失效的情况:
从执行计划看到type=ALL,Extra=Using where
走的是全表扫描,索引失效。
那么IN
索引失效的情况分为以下几种(其他的索引失效,也可以参考)
- 类型不匹配,当索引字段是字符串时,查询的参数也必须是字符串。
- 数据量
- 如果数据量很小,
MySQL
会认为扫描全表比使用索引快,自然不会走索引(优化器) - 如果查询结果数据量很多,
MySQL
也不会使用索引。 可以通过加上limit
来解决这个问题。
- 如果数据量很小,
- 排序问题
通过以上的分析,上面的索引失效情况可以通过加上limit
来解决,如下图: