题目:索引失效的问题是如何排查的,有哪些种情况?
难度:medium
标签:mysql/index
评分:⭐⭐⭐⭐☆(4/5)
索引失效先看对应 SQL 的执行计划,再查看表创建情况,确认表中是否有预期索引。如果有索引,就看执行计划是统计信息导致的失效,还是 SQL 写法有问题。检查查询值和索引字段是否存在隐式转换,比如字符串字段用数字查询;是否没遵循最左前缀、跳过了索引列;是否索引区分度不高,导致要取大量数据、回表后不如全表扫;是否 like 的百分号放在最前面;是否在索引字段上用了函数。
优点:排查顺序正确(先 EXPLAIN、再确认索引存在、再分统计问题与写法问题),主要失效场景基本齐。
不足:漏了 OR 两侧不一致、!=/NOT IN、ORDER BY 与索引顺序不匹配、统计信息过期、回表成本高于全表。
补充:EXPLAIN ANALYZE 看真实行数偏差;SHOW WARNINGS 看改写;ANALYZE TABLE 修统计;覆盖索引可消除回表。
索引失效分两类:一类是「物理上用不了」,如列上函数、隐式转换、前导百分号、最左前缀断裂;另一类是「优化器算完成本不想用」,如区分度低、回表太多、统计信息过期。排查必须先用 EXPLAIN 看 type/possible_keys/key/rows/Extra,再判断属于哪一类,而不是背口诀。
ANALYZE TABLE。OR 一定失效吗?——两侧都有索引可能走 index merge,混合无索引列则退化为全表。【一句话结论】 索引失效先看执行计划,再分「写法用不了」和「优化器不想用」两类定位。
【三点展开】 第一,用 EXPLAIN 确认预期索引是否存在、实际走了哪个,必要时 EXPLAIN ANALYZE 看真实行数。第二,写法类问题:列上函数、隐式类型转换、like 前导百分号、违反最左前缀、OR 混合无索引列。第三,成本类问题:区分度太低、回表太多、统计信息过期,可以用覆盖索引或 ANALYZE TABLE 解决。
【一句边界】 FORCE INDEX 只能兜底,不能治本;真正要改的是索引设计或 SQL 写法。