他的回复:
最左前缀原则一句话就能说清:B+ 树是按索引定义的列顺序逐列排序的,所以只能"从最左边开始连续匹配",跳列就断档。建了 idx(a, b, c),树的排序方式是先按 a 有序,a 相同再按 b 有序,a、b 相同再按 c 有序。所以:WHERE a = 1、a = 1 AND b = 2、a = 1 AND b = 2 AND c = 3 都能定位;WHERE b = 2 用不上,因为 b 只在同一个 a 内部有序,全局是乱的;WHERE a = 1 AND c = 3 只用得到 a,c 退化为回表后过滤(Extra 里通常看不到 Using index condition 的定位效果)。你问的重点——范围查询之后还能不能用:能参与索引,但只能做过滤,不能再缩小扫描范围。-- idx(a, b, c)WHERE a > 1 AND b = 2 AND c = 3这里 a > 1 是范围条件,a 一旦是范围,b 和 c 在树里就不再全局有序(不同 a 值下的 b 各自排序,跨 a 就断),所以 MySQL 只能把 a > 1 作为扫描边界,b、c 在扫出来的每一行上逐行判断。EXPLAIN 里 key_len 只算到 a 的长度,Extra 会看到 Using index condition(索引条件下推,减少回表次数,但没减少扫描范围)。所以优化方向上有个固定套路:等值列在前,范围列在后。上面那条改成 idx(b, a) 或 (b, c, a),才能让 b 的等值定位生效,把扫描范围压到最小。另外两个常被忽略的点:ORDER BY 也用同一套规则。索引列顺序与 order by 一致、且排序方向一致时才能免排序;中间插一个范围条件,后面的列排序就用不上索引了,会多出 Using filesort。WHERE a IN (1,2,3) AND b = 2 里的 IN 在优化器看来近似多个等值区间,b 仍有机会用上;但 a > 1、a BETWEEN、a LIKE 'x%' 这类连续范围就会截断后面的列。验证方法只有一个:加列改列之后跑 EXPLAIN,看 key、key_len、rows 三个值的变化,别靠背结论。