如何避免索引失效_mysql常见失效场景

来源:这里教程网 时间:2026-02-28 20:34:46 作者:

MySQL索引失效会直接导致全表扫描,查询变慢、CPU升高、锁等待加剧。避免失效的关键是理解优化器如何使用索引——它只在能利用索引有序性或等值查找的场景下才走索引。

最左前缀原则被破坏

联合索引(a,b,c)本质上是先按a排序,a相同再按b排序,b也相同时再按c排序。一旦跳过左侧列,右侧列就无法使用索引。

WHERE a = 1 AND b = 2:走索引 WHERE a = 1 AND b = 2 AND c > 3:a、b用等值,c用范围,仍走索引(c部分用于过滤,但不参与排序) WHERE b = 2 AND c = 3:没用a,索引完全失效 WHERE a > 1 AND c = 3:a是范围,b缺失,c无法利用索引

对索引列做计算或函数操作

优化器无法将表达式映射回原始索引值,只能放弃索引。

WHERE YEAR(create_time) = 2024:函数作用于列 → 全表扫描 ✅ 改为:WHERE create_time >= '2024-01-01' AND create_time 2025-01-01' WHERE UPPER(name) = 'ABC' ✅ 建函数索引(MySQL 8.0+):CREATE INDEX idx_name_upper ON t1 ((UPPER(name))),或统一存大写避免运行时转换

隐式类型转换

当查询条件与索引列类型不一致,MySQL自动转换时可能放弃索引。

❌ 字段是 VARCHAR(20),却写 WHERE col = 123(数字)→ 触发隐式转换,索引失效 ✅ 统一类型:WHERE col = '123' ⚠️ 特别注意:数值型ID字段若定义为字符串(如订单号),务必用引号;反之整型主键不要加引号

使用不满足索引特性的操作符

不是所有WHERE条件都能用上索引,尤其涉及范围、NULL、NOT等逻辑时需谨慎。

WHERE a != 1WHERE a NOT IN (1,2):通常不走索引(除非覆盖索引+优化器认为划算) WHERE a IS NULL:如果a是普通索引且允许NULL,IS NULL 可走索引;但 IS NOT NULL 在非唯一索引上常失效 WHERE a LIKE '%abc':前导通配符,无法利用B+树有序性 ✅ 改为:WHERE a LIKE 'abc%'(后缀匹配可走索引) ✅ 模糊查全字段?考虑全文索引或ES

相关推荐