哪些场景会导致索引失效?
未标记
考查重点:索引可用性与优化器选择。检查索引列函数/转换、缺联合前缀和前导模糊查询,再看优化器是否因低选择性放弃索引;用 EXPLAIN 验证
本题目录
参考答案
核心回答
以 MySQL 常见的 B+ 树索引为例,“索引失效”通常指查询不能利用某个索引有效缩小扫描范围,或者优化器判断走它成本更高,选择了其他访问方式。
常见需要检查的情况有:
- 索引列参与函数、运算或不合适的类型转换:查询比较的是处理后的值,而普通索引按原值排序,通常不能直接定位。
- 联合索引缺少前导列条件:例如索引是
(a, b, c),只按b查询,通常不能按普通的最左前缀方式定位;部分版本和查询满足条件时有跳跃扫描等例外。 - 字符串匹配以通配符开头:例如
LIKE '%abc%',普通 B+ 树难以确定可查找的前缀范围。 - 匹配数据过多或条件组合代价较高:大量二级索引扫描加回表,可能不如直接扫描表;
OR的各个分支是否有合适访问路径,也会影响选择。
还要区分:不能按条件快速定位,不代表完全没扫描索引;扫描索引,也不代表扫描得少。 !=、OR、IS NULL 都不是天然的“索引失效关键字”,应结合索引定义、数据分布和执行计划判断。
函数和类型转换为什么会影响定位?
普通索引保存并排序的是列值。对列做 DATE(created_at)、price + 1 等处理后,查询需要匹配表达式结果,通常无法直接沿原值的有序关系查找。可优先考虑把条件改成原列上的等价范围,例如按某一天查询时间列时,使用该天起点到次日起点的半开区间,同时保持时区和业务语义一致。
函数位于哪里也很重要。A = CONCAT(s1, s2) 中,如果 s1、s2 都是常量或可作为常量处理的参数,右侧可能先计算成一个值,再对 A 定位;如果它们是逐行变化的列,就不能直接作同样判断。不能只看到 SQL 中出现函数,就认定整个查询不用索引。
MySQL 也支持函数索引:查询表达式与索引表达式、结果类型和排序规则等匹配时,可以利用相应索引。因此,“对列使用函数通常影响普通索引定位”需要和“建了匹配的函数索引”分开讨论。
隐式转换同样有方向差异。带索引的字符串列与数字比较时,字符串需要按数值参与比较,多个不同字符串可能转换成同一个数字,通常不能按原字符串索引快速查找。反过来,整数列与可转换的字符串常量比较,不必然有同样结果。实际应让参数类型与列类型匹配,并检查字符集、排序规则及转换发生在哪一侧。
联合索引和模糊匹配有哪些边界?
联合索引先按第一列排序,相同后再按下一列排序,所以前导列决定了常见的定位方式。索引 (a, b, c) 可以先用 a 的等值条件缩小范围,再利用 b;若 b 使用范围比较,后续 c 通常不能继续收紧该索引区间,但仍可能用于索引内过滤或覆盖查询。WHERE 中条件的书写顺序,不等于索引列的匹配顺序。
缺少前导列时,仍可能扫描整个索引;满足覆盖查询等限制且成本合适时,MySQL 还可能采用跳跃扫描,枚举不同前导值后查找后续列。这些都不能简单归为“索引完全没用”,也不能据此忽略联合索引顺序的设计。
LIKE 'abc%' 有固定前缀,普通字符串索引可能构造范围;LIKE '%abc%' 没有这种前缀,通常无法这样定位。但若所需数据全部在索引内,优化器仍可能选择覆盖索引扫描。包含匹配是否需要专门的检索方案,要看业务搜索语义和数据规模。
怎样判断实际发生了什么?
先核对表结构、索引列顺序、参数类型、MySQL 版本和数据分布,再看 EXPLAIN:
possible_keys是可能相关的索引,key是实际选择的索引,不能只看前者。type=range表示范围访问;type=index通常是全索引扫描;type=ALL是全表扫描,三者含义不同。- 结合预估扫描行数、过滤比例和
Extra判断工作量。Using index说明覆盖访问,并不保证只读少量记录;Using index condition表示索引条件下推。
即使条件支持索引范围,优化器也可能因表很小、匹配比例高或回表成本大而选择全表扫描,没有固定的“超过某个百分比就不用索引”规则。需要实际执行信息时,可在评估执行影响后使用 EXPLAIN ANALYZE;它会真正运行查询,普通 EXPLAIN 主要给出估算。
常见追问
!= 和 OR 一定导致全表扫描吗? 不一定。B+ 树支持 != 形成范围,多个针对同一索引列的 OR 条件也可能组成多个范围。问题在于能否构造合适的访问路径,以及读出大量数据是否划算。包含无法有效定位的分支时,更容易选扫描,但不能只凭关键字下结论。
强制使用索引能解决吗? 先确认优化器为什么没选它。如果估算偏差来自统计信息,应检查统计信息;如果查询本身命中大量行,强制走二级索引反而可能增加回表。通常先调整查询、索引和返回列,再比较实际扫描量与耗时。
参考资料
- 国内:JavaGuide:MySQL 索引失效常见场景:参考函数、联合索引、模糊匹配和条件组合的分析,组织正文中常见的索引排查情形,并区分范围定位与覆盖扫描。
- 国内:JavaGuide:MySQL 执行计划分析:访问类型和
Extra字段部分说明如何区分范围访问、全索引扫描、全表扫描及索引条件下推。 - 国内:小林 coding:索引失效有哪些?:借鉴字符串列与数字比较、联合索引顺序的例子,解释正文中转换方向与索引排序如何影响定位。
- 国内:美团技术团队:MySQL 索引原理及慢查询优化:慢查询优化步骤和业务案例说明如何结合执行计划、数据分布与查询目的逐步调整,而不是仅检查 SQL 关键字。
- 国外:MySQL 8.4:Range Optimization:单列、多列范围与跳跃扫描部分给出
!=、OR、最左前缀及跳跃扫描的适用条件。 - 国外:MySQL 8.4:CREATE INDEX:函数索引部分说明表达式索引怎样参与查询,以及表达式、类型和排序规则匹配的限制。
- 国外:MySQL 8.4:Type Conversion in Expression Evaluation:字符串与数字比较规则说明为什么带索引的字符串列与数值比较,通常无法按原字符串值快速定位。
相关面经
26 篇快手
Agent 开发工程师索引失效的场景
启云方
AI 应用开发工程师如何排查索引失效?执行计划重点看哪些字段?
字节跳动
后端开发MySQL 的引擎是什么?底层数据结构?为什么不用 B 树?索引一定生效吗?
亚信科技
后端开发你写过哪些脚本?有没有遇到过 MySQL 索引失效的情况?哪些场景会导致索引失效?
中科星图维天信
后端开发展开剩余 21 篇面经
多益网络
软件开发工程师索引失效的原因有哪些?
公司未注明
测试开发岗MySQL索引底层B+树,什么场景索引会失效,说出至少4种。
字节跳动
AI 应用工程师最左前缀匹配是什么原理?为什么会失效?
美团
后端开发索引什么时候会失效?
汇川技术
全栈开发工程师MySQL索引哪些情况下会失效
顺丰
后端开发工程师mysql索引失效
字节跳动
Agent 全栈开发工程师索引失效通常是什么原因?
美团
后端开发工程师(AI)虾皮
Agent 开发工程师MySQL联合索引在什么情况下无法生效?LIKE查询在什么条件下可以使用索引?
虾皮
Agent 开发工程师什么时候索引会失效,联合索引
字节跳动
Agent 测评mysql索引失效的场景
快手
AI Agent 开发字节跳动
AI Agent滴滴
AI Agent 后端开发数据库索引的底层结构是什么?什么时候会失效?
字节跳动
后端开发工程师(AI)列举几种索引失效的常见场景。
上海景行智合安全技术
Java 开发工程师索引失效有哪些
法大大
Java 开发工程师索引失效场景
亚信科技
后端开发工程师(AI / Agent 方向)8,在什么情况下索引会失效?(不记得了)
美团
后端开发工程师MySQL 索引失效场景?`WHERE A = CONCAT(s1, s2)` 会走索引吗?
快手
后端开发a. MySQL 的索引和索引失效的情况
京东
AI 后端 / Agent 开发a. 索引失效的场景



