Range查询直接“切断”联合索引右侧字段,是因为B+树按字典序嵌套排序,范围操作(如>、

Range查询为什么直接“切断”联合索引右侧字段
因为联合索引的B+树是按字典序逐层嵌套排序的:先排第一列,值相同时再排第二列,再相同时才排第三列。一旦某列用了>、、<code>BETWEEN或LIKE 'prefix%'这类范围条件,MySQL就无法精确定位到某个子树节点,而必须扫描所有满足该范围的分支——这些分支里,后续列的值不再全局有序,索引跳转能力彻底失效。
哪些操作算Range,哪些不算
关键看是否破坏“单点定位能力”:
-
=、IN、IS NULL:保持等值路径,右侧字段仍可走索引 -
>、>=、、<code>、<code>BETWEEN、LIKE 'abc%':触发Range,右侧字段索引失效 -
!=、NOT IN、IS NOT NULL:通常等价于全范围扫描,同样截断右侧 -
LIKE '%abc'或LIKE '%abc%':不走索引,自然不涉及右侧失效问题
怎么确认右侧字段真失效了
不能只看EXPLAIN里key是否显示索引名,得盯紧两个硬指标:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
-
key_len:它表示实际用到的索引字节数。对照索引定义(比如INT是4字节,VARCHAR(50)在utf8mb4下最多200字节),就能反推出用到了第几个字段 -
Extra中是否出现Using where:如果写了WHERE a = 1 AND b > 2 AND c = 3,但Extra是Using where而非Using index,说明c = 3是回表后过滤的,没走索引
例如索引为(a INT, b VARCHAR(50), c DATETIME),查a = 1 AND b > 10 AND c = '2023-01-01'时,若key_len = 24(刚好够a+b),就证明c没参与索引查找。
重构联合索引时字段顺序怎么排
目标不是“高选择性字段放最左”,而是让**大概率被范围查询的字段尽量靠右**:
- 把必然用于等值过滤的字段(如
tenant_id、status、type)放在最左 - 把大概率参与范围查询的字段(如
created_at、amount、score)放在中间或偏右 - 把仅用于排序或覆盖查询的字段(如
SELECT中需要的列)放在最右 - 如果某字段既常被等值查、又偶尔被范围查,优先按等值场景排;若范围查询频次更高,就把它右移,同时确认左侧字段能否单独支撑大部分查询
真正容易被忽略的是:哪怕你加了FORCE INDEX,或者把ORDER BY字段也放进索引,只要WHERE里存在范围条件,右侧字段的索引加速能力就不存在——这不是配置问题,是B+树遍历逻辑决定的刚性限制。

















