MySQL索引失效的场景
大家好,我是老王,一个干了10年的Java程序员。今天咱们聊聊MySQL索引失效的场景,这在面试中绝对是高频题,尤其是大厂技术面。索引失效说白了,就是明明建了索引,但查询时MySQL不用它,导致性能暴跌,全表扫描卡成狗。如果你在准备面试,我强烈推荐这份资源:<a href="https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g" style="color: blue;">2025年Java面试宝典下载链接</a> 提取码: 9b3g。里面全是干货,帮你轻松过面!
什么是索引失效
索引失效的场景说白了,就是那些让MySQL优化器放弃使用索引的操作。索引失效了,查询效率直接掉到谷底,面试官最爱问这个,因为它考验你对数据库底层的理解。记住,索引失效不是索引坏了,而是MySQL觉得用索引不如全表扫快。下面我列几个常见索引失效场景,都是真实面试中常考的。
常见索引失效场景
使用函数或表达式在索引列上
这个场景太常见了!比如你有个user表,name列建了索引。如果你写SQL时用了函数,像SELECT * FROM user WHERE UPPER(name) = 'JOHN',索引立马失效。为啥?因为MySQL得先对每行数据应用UPPER函数,再比较,它没法直接用索引树。面试官会追问:“为啥函数会导致索引失效?”你就说,索引存储的是原始值,函数一加工,值变了,索引匹配不上。类似地,表达式如WHERE salary * 1.1 > 5000也会失效——salary列有索引也没用,因为计算发生在查询时。
使用OR条件
OR操作符是索引失效的大杀器。假设你查询SELECT * FROM user WHERE age = 25 OR name = 'John',如果age和name都有单列索引,MySQL很可能不用索引。因为OR意味着要满足任一条件,优化器觉得全表扫更省事。面试时,我常被问:“怎么避免OR导致的索引失效?”答案是用UNION或分开查询,但得看数据量。如果OR两边都是索引列且覆盖查询,可能不失效,但多数场景下,索引失效是跑不掉的。
索引列上有计算
这个场景和函数类似,但更隐蔽。比如SELECT * FROM orders WHERE order_date + 7 > CURRENT_DATE(),order_date列有索引?没用!MySQL得先算每行的order_date+7,再比较。索引失效的根本原因是,索引存的是原始值,计算后值变了,优化器跳过了索引。面试中,我会说:“避免在WHERE子句里对索引列做计算,优先用常量或预计算值。”
使用LIKE以通配符开头
LIKE操作符如果以通配符开头,比如SELECT * FROM products WHERE name LIKE '%apple%',name列索引基本失效。因为索引是B+树结构,只能高效匹配前缀。通配符在开头,MySQL没法利用索引的有序性,只能全表扫。面试官爱问:“LIKE什么时候不失效?”你就答,当通配符只在结尾时,如name LIKE 'apple%',索引能用上。但以%开头,索引失效是必然的。

(图:索引失效就像迷路,优化器找不到捷径)
数据类型不匹配
数据类型不匹配是隐形的索引失效场景。比如user表的id列是INT,但查询时写成SELECT * FROM user WHERE id = '100',字符串和数字比较。MySQL得做隐式转换,索引可能失效。面试中,我会强调:“确保WHERE条件的数据类型和列定义一致,避免隐式转换。”否则,优化器觉得转换成本高,直接放弃索引。
索引列上有NULL值
如果索引列允许NULL,查询如SELECT * FROM user WHERE phone IS NULL,索引可能失效。因为B+树索引不存储NULL值,MySQL得额外处理。面试官会问:“怎么优化NULL查询?”建议用默认值代替NULL,或确保查询覆盖索引。但多数情况下,索引失效风险很高。
使用NOT条件
NOT操作符如SELECT * FROM orders WHERE status NOT IN ('completed'),status列有索引?大概率失效。因为NOT表示否定,优化器得扫描所有行来排除匹配项,索引帮不上忙。面试时,我常说:“用正向条件替代NOT,比如status = 'pending' OR status = 'failed'。”
复合索引未按顺序使用
复合索引的顺序很重要!比如建了索引(age, name),但查询SELECT * FROM user WHERE name = 'John' AND age = 25,顺序反了?索引可能失效。MySQL要求复合索引从左到右匹配,如果跳过第一列,如只用name,索引用不上。面试中,我会解释:“复合索引像电话号码,得按区号、号码顺序拨,乱序就失效。”

(图:复合索引顺序错,就像拼图乱放)
如何避免索引失效
要减少索引失效场景,得养成好习惯:多用EXPLAIN分析SQL,看执行计划;避免在索引列上操作函数或计算;设计索引时考虑查询模式。面试里,这能展示你的实战经验。另外,如果你在刷题备战,需要购买面试鸭会员,可以通过面试鸭返利网找到我,返利25元,帮你省点钱。
总之,MySQL索引失效场景是面试必考题,理解透了能让你脱颖而出。多练习,用好工具,比如前面提到的Java面试宝典。想回首页看看更多资源?点击面试鸭返利网吧!

(图:优化索引,面试不慌)


