MySQL索引失效深度剖析
这里分享一份 2025年Java面试宝典:
链接: https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g
提取码: 9b3g
索引失效的底层逻辑
面试常被问:"明明加了索引,查询为啥还慢?" 核心在于索引失效。想象你在图书馆按作者名找书,管理员(MySQL)却坚持遍历所有书架——这就是索引失效的灾难现场。
高频索引失效场景解析
1. 最左前缀原则遭破坏
联合索引 (name, age) 时:
-- ✅ 走索引:
SELECT * FROM users WHERE name = '张三'
SELECT * FROM users WHERE name = '张三' AND age = 25
-- ❌ 失效:
SELECT * FROM WHERE age = 25 -- 跳过了name!

2. 函数/计算操作
对字段进行任何处理都会让索引罢工:
SELECT * FROM users WHERE YEAR(create_time) = 2023 -- 索引直接无视
3. 隐式类型转换陷阱
字段定义为 varchar 却用数字查:
SELECT * FROM users WHERE phone = 13800138000 -- phone是字符串类型!
MySQL内部执行了 CAST(phone AS INT),导致索引失效。
如何精准定位索引失效
EXPLAIN命令是照妖镜:
关注这几个关键字段:
| Type | Key | Extra | 诊断结论 |
|-------|---------|----------------|----------------------|
| ALL | NULL | Using filesort | 全表扫描,索引失效! |
| ref | idx_name| NULL | 索引正常生效 |

面试实战解决方案
场景: 面试官问:"用户表根据手机尾号查询怎么优化?"
失效方案:
WHERE RIGHT(phone,4)='6789' ❌
优化方案:
-- 新增冗余字段
ALTER TABLE users ADD phone_suffix VARCHAR(4);
CREATE INDEX idx_phone_suffix ON users(phone_suffix);
-- 查询时走索引
SELECT * FROM users WHERE phone_suffix='6789' ✅
注意覆盖索引陷阱:
SELECT * FROM table WHERE a=1 AND b=2 -- 联合索引(a,b)时可能回表
SELECT a,b FROM table WHERE a=1 AND b=2 -- 覆盖索引避免回表
永久避坑指南
- 避免索引列参与计算:把计算转移到代码层
- LIKE左模糊禁用:
LIKE '%abc'绝对失效 - OR条件拆UNION:
WHERE a=1 OR b=2改SELECT...UNION SELECT... - IS NULL需谨慎:
WHERE name IS NULL可能失效(数据分布决定)
🎁 特别提示:在购买面试鸭会员前,通过 面试鸭返利网 联系我可返25元!海量MySQL优化真题已收录在会员题库中。



