Skip to Content
面试题库Mysql[面试题] 什么是最左前缀匹配?为什么要遵守?

[面试题] 什么是最左前缀匹配?为什么要遵守?

📖 版块 A:知识讲解版 (温故知新)

  • 定义:最左前缀匹配(Leftmost Prefix Match)是数据库复合索引(联合索引)中的一个核心准则。指在查询时,只有按照索引定义的列顺序,从最左边的列开始连续匹配,索引才能生效或部分生效。

  • 匹配规则

    1. 如果建立了索引 (a, b, c),查询条件包含 a,则可以使用索引;包含 a, b,也可以使用;包含 a, b, c,全覆盖使用。
    2. 如果跳过中间列,如 a, c,则只能用到 a 列的索引,c 列无法利用索引定位。
    3. 如果没有最左列,如只查询 bc,则完全无法使用该索引(通常会触发全表扫描)。
  • 失效场景

    1. 断位:查询条件中不包含联合索引的最左列。
    2. 范围查询后失效:在联合索引中,如果某列使用了范围查询(如 >, ` 🧠 破局思路:面试官不仅想听你背诵“a-b-c”的规则,他更看重你是否理解 B+ Tree 联合索引的底层物理结构。真正的区分度在于:能否从 B+ 树的排序逻辑出发解释原因,以及能否点出“范围查询导致后续列失效”的底层细节。

💬 高手逐字稿

简单来说,最左前缀匹配是指在使用联合索引时,MySQL 优化器会从索引的最左侧列开始逐一匹配。如果查询条件中没有包含索引的最左列,或者中间断开了,那么索引就无法被充分利用。

为什么要遵守这个原则?这得从 B+ Tree 的底层逻辑说起。

联合索引在物理存储上只有一棵 B+ 树,它的非叶子节点存储的是多个列的值。这些值是严格按照定义索引时的顺序进行排序的。以索引 (a, b) 为例,在 B+ 树中,数据首先按照 a 列进行全局排序;只有在 a 列的值相等的情况下,b 列的值才是局部有序的。

因此,如果你跳过 a 直接去查 b,由于 b 在全局范围内是乱序的,索引就无法通过二分查找快速定位,只能退化成全表扫描。这就是为什么要遵守最左前缀的原因:索引的有序性是建立在左侧列的基础之上的。

这里有一个非常容易被忽略的细节,就是“范围查询”对最左前缀的影响。

在联合索引中,如果我们在某个列上使用了范围查询(比如 a > 10),那么虽然 a 这一列能用到索引,但由于 a 的值已经不固定了,其右侧的 b 列在整个 a > 10 的范围内是无序的。所以,从范围查询那一列开始,后面的索引字段都会失效。

不过在面试中,我经常会碰到一个误区: 有人认为 WHERE b=1 AND a=1 这种写法不符合最左前缀,因为 b 写在了前面。这其实是不对的。MySQL 的查询优化器(Optimizer)会自动调整 WHERE 子句中的条件顺序,使其匹配索引定义的顺序。所以,只要条件里包含了最左列,顺序并不影响索引的命中。

另外,从 MySQL 8.0 开始,引入了“索引跳跃扫描(Index Skip Scan)”,在某些特定场景下(比如左侧列基数很小),即使没有最左列,优化器也可能通过多次扫描索引块来利用索引,但这属于优化器的特例,在设计索引时,我们仍然必须严格遵守最左前缀原则。

最后更新于:
⏱️

登录后开始阅读

当前 MVP 版本只开放邮箱密码登录注册。完成登录后即可进入面试题内容。

还没有账号?先去注册