联合索引 ABC 遇到 A=1、B>10、C=5 时如何生效,为什么范围条件会影响索引?
未标记
考查重点:范围定位与后续列过滤。A 等值后 B 范围可缩小扫描;C 通常不能继续形成单一连续定位范围,但可在索引层过滤,不能说完全失效
本题目录
参考答案
核心回答
对按 (A, B, C) 排序的联合 B+ 树索引,A=1 先锁定相同 A 的区域,B>10 再限定扫描范围;C=5 通常不能继续把这个范围缩成一个连续区间,因为不同 B 值下面的 C=5 分散在多个位置。但 C 并不是完全没用:扫描索引时仍可检查 C,符合条件才回表,或者在覆盖索引中直接完成过滤。
因此要分清三件事:哪些列构造索引扫描边界,哪些条件能在索引层过滤,以及查询是否需要回表。不能一句“遇到范围后面的列失效”把它们混在一起。
用具体排列理解
假设索引中依次有 (1,11,2)、(1,11,5)、(1,12,1)、(1,12,5)。B>10 的记录连续,但满足 C=5 的两条记录之间夹着不满足条件的记录。扫描仍要跨过这些位置,再检查 C。
在 InnoDB 二级索引的适用条件下,ICP(索引条件下推)可先检查索引上的 C,减少读取完整行的次数。若查询所需列已被索引覆盖,可能根本不需要按主键回表,这与 ICP 又是不同的优化点。
如何检查、怎样调整索引
用 EXPLAIN 或适当环境下的 EXPLAIN ANALYZE 查看实际访问路径、扫描与返回行数,结合 Using index condition、Using index 等信息解释,不能只看 key_len 就断言每一列都用于同一种过滤。
若这类查询很重要,可以评估 (A,C,B):先处理两个等值条件,再扫描 B 的范围,通常能形成更窄的区间。但还要考虑其他查询、排序和写入成本,不能因为一道题就无条件调整索引。
这里讨论的是题干明确的 B>10。其他比较符、组合条件、索引类型与优化器选择需要单独分析,不应把这个结论机械推广到每一种范围查询。
参考资料
- 国内:JavaGuide:MySQL索引:采用联合排序与回表成本的解释,区分扫描、过滤和覆盖索引。
- 国内:JavaGuide:MySQL索引失效:采用范围条件之后仍可过滤的分析;具体
MySQL行为另按官方文档核对。 - 国内:PingCAP:索引选择:借鉴索引读取与回表的成本区分,解释优化不能只看是否命中索引。
- 国内:PingCAP:谓词下推:采用尽早过滤降低后续读取与处理成本的机制;不将
TiDB算子等同MySQLICP。 - 国外:MySQL 8.4:Range Optimization:核对复合索引如何构造范围,以及遇到大于条件后的后续列范围提取边界。
- 国外:MySQL 8.4:Index Condition Pushdown:核对
InnoDB二级索引下推与减少完整行读取的适用条件。

