联合索引不是几个单列索引简单拼在一起,而是一棵按多个字段依次排序的 B+ 树。能不能利用它,首先取决于查询条件是否沿着这棵树的排序方向连续前进。

最左前缀讲的是有序性的使用边界,覆盖索引讲的是能否避免回表。一个决定“怎么走索引”,一个决定“走完索引后还要不要回主键树”。

先把机制边界说清楚

联合索引不是多个索引简单相加,而是一棵按多个字段依次排序的 B+ 树。最左前缀说明这棵树只能从左往右连续利用有序性;覆盖索引则说明查询所需列都能在索引里拿到,不必再回主键树。

整体路径

覆盖索引与最左前缀:联合索引怎么设计

上面这张图先看粗线条:宏观上,一个优秀联合索引要同时回答三件事:先用哪些字段缩小扫描范围,接着能否复用索引顺序完成排序,最后返回列是否能被索引覆盖。它不是为单条 SQL 临时造的补丁,而是为一类稳定访问模式设计的路径。

底层流程

覆盖索引与最左前缀:联合索引怎么设计:执行路径

底层拆解先看数据结构。「覆盖索引与最左前缀」至少涉及下面几类结构:

  • 联合键编码:按字段顺序拼接比较,前一列相同才比较后一列。
  • 叶子节点:保存联合键和主键值,天然按联合键有序。
  • 覆盖列:在索引叶子里已经存在的返回列。
  • 范围边界:一旦出现范围条件,后续列用于定位的能力下降。

再看完整执行流程:

  1. 等值条件命中最左字段。
  2. 继续利用后续等值字段缩小范围。
  3. 遇到范围字段后定位扫描区间。
  4. 如果 order by 与索引顺序一致,避免 filesort;如果 select 列被覆盖,避免回表。

取舍与边界

版本差异上,MySQL 8.0 对降序索引支持更完整,混合排序场景比 5.7 更容易复用索引顺序。8.0 的 invisible index 也让索引验证更安全,可以先隐藏观察执行计划影响。

联合索引最大的问题是过度定制。字段顺序服务 A 查询,可能完全服务不了 B 查询;为了覆盖返回列不断加字段,会让索引变宽,写入和缓存成本上升。

典型问题:用机制化例子排查

联合索引失效常常不是索引没建,而是查询没有沿最左前缀连续利用有序性。覆盖索引能减少回表,但前提是索引顺序和查询列真的对得上。

可以落到这些动作:

  • 字段顺序优先服务高频查询,不追求一个索引覆盖所有场景。
  • 等值过滤列通常靠前,范围和排序列靠后,但要结合区分度和排序需求。
  • 覆盖索引适合高频读接口,写密集表要控制索引宽度。
  • 分页场景优先设计游标式访问路径,而不是深 offset。

收束:先用顺序,再省回表

最左前缀解决的是能不能连续利用索引顺序,覆盖索引解决的是能不能不回表。两个问题分清楚,联合索引设计就不会只停在字段堆叠。


关于十三Tech

我是十三,All in AI Agent 方向的架构师,专注 AI 工程实践。

我相信 AI 是程序员的最佳搭档,也希望帮助每一位开发者更好地驾驭 AI。

如果你想继续跟完这套「图解 MySQL」,欢迎关注公众号 「十三Tech」。后续会继续按机制、图解和实战排查这条线更新。

十三Tech公众号二维码