60 秒回答模板

以联合索引 (a, b, c) 为例,索引首先按 a 排序,a 相同再按 b 排序,a 和 b 都相同再按 c 排序。因此查询条件从 a 开始连续匹配时,索引利用最充分,例如 a = ?、a = ? and b = ?、a = ? and b = ? and c = ?。如果跳过 a 只查 b 或 c,通常无法利用这个联合索引做有效定位。范围条件会影响后续列的继续定位,例如 a = ? and b > ? 可以用到 a 和 b 的范围,但 c 往往不能再用于精确缩小扫描范围。最左前缀不仅用于 where,也影响 order by 和 group by:排序字段顺序与索引前缀一致时才更可能避免额外排序。实际优化还要看覆盖索引、索引下推、优化器成本和数据选择性。

考点 本质是复合排序
难度 真实面经高频题
回答目标 讲清机制、边界和追问

深入解析

01

联合索引的排序方式

联合索引不是给每一列各建一棵独立索引,而是按列顺序组成复合键。对于 (a, b, c),B+ 树先按 a 有序,a 相同时按 b 有序,a、b 都相同时按 c 有序。正因为排序是分层的,只有从左侧列开始限定,后面的列才处在可连续定位的有序范围内。

02

连续前缀才能定位

查询 a、a+b、a+b+c 都符合连续前缀;只查 b、只查 c、查 b+c 却不限制 a,通常无法利用该联合索引快速定位起点。原因是不同 a 值下面的 b 并不形成全局连续顺序,数据库无法直接按 b 做一次窄范围扫描。

03

范围条件后的限制

等值条件可以继续向右推进索引匹配,范围条件会让后续列的定位能力下降。例如 a = 1 and b = 2 and c = 3 可以连续命中三列;a = 1 and b > 2 and c = 3 中,c 可能只能作为过滤条件,而不能继续把扫描范围精确缩到一个点。

04

排序分组同样受影响

最左前缀不只影响 where。order by a, b 或 group by a, b 与索引顺序一致时,更可能利用索引有序性;若 order by b 或顺序与索引不一致,通常需要额外排序。若 where 中前导列是等值条件,后续列的排序有时也能继续利用索引顺序。

05

实际执行看优化器

最左前缀是重要原则,但不是机械规则。优化器会结合统计信息、选择性、回表成本、索引下推、覆盖索引和数据量选择执行计划。某些场景下即使不完全满足前缀,也可能出现索引扫描或跳跃扫描等优化;面试中应先讲原则,再补充执行计划验证。

易错点

  • 把最左前缀理解成 SQL 条件书写顺序必须和索引顺序一致。
  • 认为联合索引里的任意列都能独立高效使用。
  • 忽略范围条件会影响后续列继续用于精确定位。
  • 只考虑 where,不考虑 order by、group by、覆盖索引和回表成本。

面试官追问

where 条件书写顺序会影响最左前缀吗?

通常不会。优化器会重排等值条件,where b = ? and a = ? 仍可能使用 (a, b) 索引。真正重要的是联合索引定义顺序和条件是否能形成连续前缀,而不是 SQL 文本里的先后顺序。

like 查询什么时候能用索引?

like 'abc%' 这种固定前缀可以利用有序索引做范围扫描;like '%abc' 或 like '%abc%' 前面没有确定起点,通常无法利用普通 B+ 树索引高效定位。

联合索引 (a, b, c) 查询 a = 1 and c = 3 能用几列?

通常 a 能用于定位,c 因为跳过 b 不能作为连续前缀继续定位,但可能在索引下推或扫描过程中作为过滤条件使用。如果查询列都在索引里,还可能减少回表。

为什么不能给所有查询都建一个很长的联合索引?

索引越长,存储越多,写入和更新维护成本越高,缓存命中率也可能下降。很长的索引还不一定匹配高频查询前缀。索引设计要围绕稳定高频查询和收益成本平衡。