哪些场景会导致索引失效?

考查重点:索引可用性与优化器选择。检查索引列函数/转换、缺联合前缀和前导模糊查询,再看优化器是否因低选择性放弃索引;用 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 条件也可能组成多个范围。问题在于能否构造合适的访问路径,以及读出大量数据是否划算。包含无法有效定位的分支时,更容易选扫描,但不能只凭关键字下结论。

强制使用索引能解决吗? 先确认优化器为什么没选它。如果估算偏差来自统计信息,应检查统计信息;如果查询本身命中大量行,强制走二级索引反而可能增加回表。通常先调整查询、索引和返回列,再比较实际扫描量与耗时。

参考资料

相关面经

26 篇

快手

Agent 开发工程师
秋招一面
查看原面经 →
索引失效的场景

启云方

AI 应用开发工程师
一面
查看原面经 →
如何排查索引失效?执行计划重点看哪些字段?

字节跳动

后端开发
日常实习一面、二面
查看原面经 →
MySQL 的引擎是什么?底层数据结构?为什么不用 B 树?索引一定生效吗?

亚信科技

后端开发
实习
查看原面经 →
你写过哪些脚本?有没有遇到过 MySQL 索引失效的情况?哪些场景会导致索引失效?

中科星图维天信

后端开发
实习
查看原面经 →
哪些情况会导致索引失效?请举例说明。
为什么禁止 SELECT * ?函数操作对索引有什么影响?
展开剩余 21 篇面经

多益网络

软件开发工程师
秋招一面、二面
查看原面经 →
索引失效的原因有哪些?

公司未注明

测试开发岗
一面、二面、三面
查看原面经 →
MySQL索引底层B+树,什么场景索引会失效,说出至少4种。

字节跳动

AI 应用工程师
一面
查看原面经 →
最左前缀匹配是什么原理?为什么会失效?

美团

后端开发
一面
查看原面经 →
索引什么时候会失效?

汇川技术

全栈开发工程师
查看原面经 →
MySQL索引哪些情况下会失效

顺丰

后端开发工程师
一面
查看原面经 →
mysql索引失效

字节跳动

Agent 全栈开发工程师
一面
查看原面经 →
索引失效通常是什么原因?

美团

后端开发工程师(AI)
秋招一面
查看原面经 →
什么情况MySQL优化会不走索引变成全表扫描
索引什么情况会失效

虾皮

Agent 开发工程师
秋招一面
查看原面经 →
MySQL联合索引在什么情况下无法生效?LIKE查询在什么条件下可以使用索引?

虾皮

Agent 开发工程师
一面
查看原面经 →
什么时候索引会失效,联合索引

字节跳动

Agent 测评
一面
查看原面经 →
mysql索引失效的场景

快手

AI Agent 开发
一面
查看原面经 →
数据库索引失效的情况有哪些?
like 查询会不会导致索引失效?

字节跳动

AI Agent
秋招一面
查看原面经 →
MySQL 索引在什么情况下会失效?
使用 LIKE 进行模糊查询时,索引什么情况下会失效?

滴滴

AI Agent 后端开发
查看原面经 →
数据库索引的底层结构是什么?什么时候会失效?

字节跳动

后端开发工程师(AI)
实习一面
查看原面经 →
列举几种索引失效的常见场景。

上海景行智合安全技术

Java 开发工程师
实习一面、二面
查看原面经 →
索引失效有哪些

法大大

Java 开发工程师
实习一面
查看原面经 →
索引失效场景

亚信科技

后端开发工程师(AI / Agent 方向)
查看原面经 →
8,在什么情况下索引会失效?(不记得了)

美团

后端开发工程师
暑期实习一面
查看原面经 →
MySQL 索引失效场景?`WHERE A = CONCAT(s1, s2)` 会走索引吗?

快手

后端开发
日常实习一面
查看原面经 →
a. MySQL 的索引和索引失效的情况

京东

AI 后端 / Agent 开发
日常实习一面
查看原面经 →
a. 索引失效的场景

收录题集

2 个来源,共2 份题集

字节跳动高频面试题

Rocky Ding · AIGC-Interview-Book · 2 条原题

查看题集 →

工程化踩坑:死循环、状态丢失与成本控制

Onefly · zero2Agent · 1 条原题

查看题集 →

相关题目

4 题