MySQL索引失效场景总结
索引失效不是神秘现象,多是谓词写法、类型或统计信息让优化器放弃索引。
高频失效场景
- 对索引列使用函数或运算:
WHERE YEAR(d)=2026。 - 隐式类型转换(见专题文)。
- 联合索引不满足最左前缀。
- 使用
!=、NOT IN、OR(部分可 merge,部分全扫)。 LIKE '%xx'前缀通配。- 优化器判断回表成本高于全表扫(小表或选择性差)。
验证方法
1 | EXPLAIN SELECT * FROM t WHERE ...; |
优化思路
改写 SQL 让谓词「索引用得上」;增加覆盖索引减少回表;必要时分区或归档冷数据。
优化器成本模型
rows 估算是统计信息驱动,数据分布突变后需 ANALYZE。histogram(8.0)改善选择性估计。
索引合并
index merge union/intersection 有时替代联合索引,但不一定稳定。
实践复习清单
收集 ten 条失效 SQL 改写对照;ANALYZE 后 replan;覆盖索引设计练习;filesort 告警;冗余索引清理;最左前缀 violations 扫描。
常见坑
- 见 key 列有值就认为走索引,忽略 rows 与 Extra 中 Using where/filesort。
- 盲目加索引导致写入变慢与优化器选择混乱。
总结与自测
背出八种失效场景;会用 EXPLAIN 验证;知道何时 statistics 过期;理解优化器选全表扫原因。每周选一条生产慢 SQL 做失效分析练习,进步最快。
原理延伸
InnoDB 的核心竞争力在于把 B+ 树索引、缓冲池、redo/undo 与 MVCC 组合成可预测的 OLTP 引擎。读路径尽量走缓冲池与覆盖索引,写路径则要在行锁、日志刷盘与复制延迟之间取平衡。排查问题时不要只盯单条 SQL,还要看事务边界、锁等待、buffer pool 命中率与磁盘 fsync 延迟。性能优化永远遵循「先正确、再可测、后优化」:用慢日志和 EXPLAIN 定位瓶颈,用规范设计减少回表与锁竞争,用架构手段(读写分离、缓存、分片)承接流量,而不是在未测量前堆参数。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Dai Wei!
评论

