索引失效场景清单

共 17 题
#

1. 导致索引失效的完整场景清单,隐式类型转换、函数包裹列、前导通配符 LIKE、OR 连接非索引列、隐式排序规则不一致——各自的原理与改写方案?

A LIKE '%x' 可以利用索引范围扫描
B 隐式类型转换与函数包裹列等价于"列被计算"使 B-Tree 无法命中,前导 LIKE 无法定界,OR 非索引列与 collation 不一致同样失效,各有对应改写 ✓ 正确答案
C 隐式类型转换不影响索引使用
D collation 不一致不影响 JOIN 索引
#

2. 为什么 IS NULL/IS NOT NULL、!= 不一定走索引?优化器基于成本的选择逻辑如何验证?

A IS NULL/!= 走不走索引由成本决定:匹配行占比高时回表代价大于全表扫描;PG 与 InnoDB 的 B-Tree 索引都存储 NULL,IS NULL 均可匹配索引,但高占比时成本估算仍会选全表 ✓ 正确答案
B MySQL 二级索引不存储 NULL 值
C 该选择与统计信息无关
D 这些条件在任何情况下都走索引
#

3. 复合索引的最左前缀原则,哪些查询模式会"部分使用"索引(如跳过中间列)?Index Skip Scan 如何缓解?

A 复合索引只能按列序消费条件,跳过中间列会退化为部分使用,Index Skip Scan 通过枚举前缀列不同值多次探测缓解缺前缀查询,但前缀基数过大时无效 ✓ 正确答案
B 跳过中间列不影响后续列使用索引
C Index Skip Scan 只适用于高基数前缀列
D 最左前缀允许跳过任意中间列
#

4. 索引失效的常见场景(函数、隐式转换、前导模糊、OR 等)如何系统排查?

A key_len 反映的是回表次数
B 排查应从 EXPLAIN 的 type/key/key_len/Extra 入手,结合失效场景清单归因,再做改写与建索引并回归验证 ✓ 正确答案
C EXPLAIN 无法看出索引使用情况
D 慢日志对定位慢 SQL 没有帮助
#

5. IS NULL/IS NOT NULL 在 InnoDB 二级索引上的扫描方式,覆盖索引为何可以优化 NULL 查询

A IS NULL 在 InnoDB 中永远走全表
B InnoDB 二级索引不存储 NULL 值
C InnoDB 二级索引存储 NULL 且 NULL 排在最左,IS NULL 可走索引,覆盖索引使 NULL 查询零回表显著优于回表路径 ✓ 正确答案
D 覆盖索引会增加回表次数
#

6. IN 与 EXISTS 的选择,不同数据分布下优化器如何改写?半连接优化的适用条件?

A IN 永远比 EXISTS 快
B 半连接优化与数据分布无关
C IN/EXISTS 被优化器统一改写为半连接,并按代价在 firstmatch、物化等策略中选择,SQL 写法差异通常不影响计划 ✓ 正确答案
D 带 LIMIT 的子查询也可以安全展开
#

7. ORDER BY 利用索引避免 filesort 的条件清单(方向一致性、最左匹配、覆盖)?

A 排序方向不一致也可以免排序
B 免 filesort 要求 ORDER BY 列与 WHERE 等值列构成连续索引前缀、方向一致且无范围间断 ✓ 正确答案
C 覆盖索引必然免 filesort
D 范围条件不会截断后续列的排序能力
#

8. 索引列参与计算(WHERE id + 1 = 10)或表达式(对 created_at 使用 YEAR() 函数)为何失效?函数索引(Functional Index)如何补救?

A 函数索引没有写入成本
B 函数索引不需要查询表达式与之匹配
C 对列做计算或函数包裹后索引键序无法定位,需改写为范围条件或建函数/表达式索引,且查询表达式必须与索引表达式一致 ✓ 正确答案
D 计算列不影响索引使用
#

9. 字符集/排序规则不一致(utf8mb4 vs utf8)导致 JOIN 时索引失效的排查与修复?

A EXPLAIN 无法体现该问题
B collation 不影响索引使用
C 隐式转换不需要借助索引
D JOIN 两侧 collation 不同会触发隐式转换使列被包裹、索引失效,应统一列定义(CONVERT TO CHARACTER SET)根治 ✓ 正确答案
#

10. "索引未失效但走全表"的统计信息问题,直方图、采样与 optimizer 选择?

A 只要索引存在优化器必定使用
B 直方图对倾斜列没有任何帮助
C 选择率高时强制索引是最优解
D 索引未失效却走全表多为统计问题(陈旧、采样不足、缺直方图高估选择率)或回表代价被高估,应刷新统计、建直方图或校准代价参数 ✓ 正确答案
#

11. 复合索引的列顺序与过滤/排序/覆盖的匹配规则,如何设计最优列序?

A 复合索引列序按"等值列(常用高区分度在前)→ 排序列(方向一致)→ 范围列 → 覆盖列"设计,等值列顺序可互换 ✓ 正确答案
B 覆盖列应放在最前面
C 排序列与等值条件无关
D 范围列应放在最前面
#

12. 索引下推(ICP)与覆盖索引在 InnoDB 中的实际收益场景?

A ICP 与条件类型完全无关
B ICP 在索引扫描时提前过滤非前缀条件减少回表(Using index condition),覆盖索引零回表(Using index),两者都优化 InnoDB 二级索引回表成本 ✓ 正确答案
C ICP 会增加回表次数
D 覆盖索引只在全表扫描时生效
#

13. OR 条件与索引,什么情况下 OR 会导致索引失效,如何改写?

A IN 无法替代等值 OR
B OR 永远走索引合并
C 任一分支无索引也能走索引合并
D OR 的每个分支都可用索引时优化器才走 index merge/bitmap or,任一分支无索引则常退化为全表,等值 OR 可改写为 IN ✓ 正确答案
#

14. MySQL 前缀索引(INDEX(col(10)))的失效边界与选择依据

A 前缀索引可以作覆盖索引
B 前缀索引支持 ORDER BY 全列排序
C 前缀长度不影响选择性
D 前缀索引只含前 N 字符,无法用于全列排序与覆盖,选择率按前缀去重计算,长度取"接近全列选择率的最小 N" ✓ 正确答案
#

15. 统计信息过期导致优化器误判索引选择,如何通过 ANALYZE TABLE / pg_stat_statements 发现并修复?

A ANALYZE 无法改变执行计划
B 统计过期只影响写入性能
C pg_stat_statements 直接给出统计正确性
D 统计过期使 rows 误估导致索引与 join 误判,可用 EXPLAIN ANALYZE 对比估算与实际、查 n_mod_since_analyze 发现,ANALYZE 后修复 ✓ 正确答案
#

16. "优化器选错索引"的案例排查,force index、统计信息刷新与直方图?

A 选错索引的排查用 EXPLAIN/optimizer trace 归因,修复顺序为刷新统计→直方图/扩展统计→代价参数→FORCE INDEX 临时止血 ✓ 正确答案
B optimizer trace 无法查看索引选择依据
C FORCE INDEX 是根治手段
D 直方图对倾斜列无效
#

17. 使用 EXPLAIN ANALYZE 与 optimizer trace 定位索引选择的完整流程

A optimizer trace 只输出执行结果
B 定位流程为慢 SQL 捕获→EXPLAIN 初判→EXPLAIN ANALYZE 对比估算与实际→optimizer trace 深挖选择依据→归因修复→回归验证 ✓ 正确答案
C EXPLAIN ANALYZE 不会真实执行 SQL
D auto_explain 不能自动记录计划