mysql索引失效的场景总结
大家好,我是老王,一个干了10年的Java后端程序员。今天咱们来聊聊面试中常被问到的MySQL索引失效问题。索引失效这事儿,搞不好会让你的查询慢如蜗牛,数据库性能直接崩盘。在面试里,这绝对是高频考点,面试官最爱揪着问。先给大家送个福利:2025年Java面试宝典下载:点击这里获取 提取码: 9b3g。这份宝典涵盖了最新Java面试题,包括数据库优化,绝对值得收藏!
为什么索引失效这么重要?
索引失效的场景总结起来,就是MySQL没用到索引,导致全表扫描。想想看,一张大表几百万行,如果索引失效,查询时间从毫秒级飙升到秒级,用户体验直接崩了。在面试中,面试官会问:“说说哪些场景会让索引失效?”你得脱口而出几个例子,证明你懂优化。今天我就以程序员的角度,口述这些常见场景,帮大家轻松应对面试。
场景一:在索引列上使用函数或表达式
索引失效的第一个场景,就是在索引列上用了函数或表达式。比如,你有个user表,name列加了索引。你写查询:SELECT * FROM user WHERE UPPER(name) = 'JOHN'。这里用了UPPER函数,MySQL没法直接用索引,因为它得先计算所有行的name值,再比较。结果就是索引失效,全表扫描。面试时,面试官可能追问:“为什么函数会导致索引失效?”你就说,索引是基于列原始值建的,加了函数就破坏了匹配规则。

场景二:LIKE查询以通配符开头
第二个常见索引失效场景,是LIKE查询以%开头。假设你索引了email列,查询SELECT * FROM user WHERE email LIKE '%gmail.com'。开头的%表示任意字符,MySQL不知道从哪匹配,只能扫描全表。索引直接失效!但如果写成LIKE 'john%@gmail.com',索引还能用,因为开头是固定值。面试中,面试官常问:“如何优化LIKE查询?”你就提避免开头通配符,或者用全文索引。
场景三:数据类型不匹配
索引失效的第三个场景,是查询条件的数据类型和索引列不匹配。比如,age列是整数索引,你写WHERE age = '25'(字符串)。MySQL得做隐式转换,把字符串转数字,这过程索引用不上,导致失效。面试时,面试官可能说:“为什么类型不匹配会失效?”解释为,索引存储的是原始类型值,转换破坏了索引结构。

场景四:使用OR条件
第四个索引失效场景,是查询中用OR连接多个条件。例如,SELECT * FROM user WHERE name = 'John' OR age = 30。如果name和age都有索引,但MySQL可能只用一个索引,另一个失效。更糟的是,如果OR条件涉及不同列,优化器直接放弃索引,全表扫描。面试中,面试官会问:“怎么避免OR导致的失效?”建议用UNION或拆分成多个查询。
场景五:索引列参与计算
第五个场景,索引列在查询中参与计算。比如,salary列有索引,你写WHERE salary * 1.1 > 5000。MySQL得计算每行的salary * 1.1,索引失效。面试时,面试官常考这个,你就说:“把计算移到右边,写成WHERE salary > 5000 / 1.1,索引就能用。”
场景六:使用NOT或<>操作符
第六个索引失效场景,是用NOT或<>操作符。例如,WHERE status <> 'active',如果status有索引,MySQL可能觉得扫描全表更快,因为非等值查询匹配范围大。索引失效常见于低基数列(值重复多)。面试中,面试官问:“为什么NOT会失效?”解释为优化器认为全表扫描更高效。
场景七:全表扫描更优时
第七个场景,是当数据量小或索引选择性低时,MySQL选择全表扫描。比如,表只有100行,或者索引列值重复率高(如gender列),优化器觉得用索引不如直接扫表快。索引失效在这里是主动选择。面试时,面试官可能问:“怎么判断索引该不该用?”你就说看执行计划(EXPLAIN),关注rows和type。

场景八:复合索引未用最左前缀
第八个索引失效场景,是复合索引没用到最左前缀。比如,你建了索引(name, age),查询WHERE age = 30,没带name,索引失效。因为复合索引按顺序存储,跳过左边列就用不了。面试中,面试官爱问:“复合索引怎么设计?”强调最左前缀原则。
如何避免索引失效?
总结这些索引失效场景,核心是理解MySQL优化器逻辑:它只认原始值和精确匹配。面试时,多提用EXPLAIN分析查询,避免函数、通配符开头和类型转换。如果你在准备面试,需要系统学习,可以考虑面试鸭会员——通过面试鸭返利网购买,能返利25元,性价比超高!会员题库覆盖所有数据库优化题,助你轻松过关。好了,今天就聊到这儿,大家快去下载那份Java宝典吧!


