面试知识库
极高 基础

最左前缀原则#

一句话答案#

联合索引 (a,b,c) 只有从最左列开始连续匹配才能走索引,跳过中间列或范围查询后的列无法使用索引。

核心要点

联合索引的底层结构: 索引 (a, b, c) 的 B+ 树叶子节点,数据先按 a 排序,a 相同时按 b 排序,b 相同时按 c 排序。

最左前缀原则: 查询条件必须从索引的最左列开始匹配,不能跳过中间列。

-- 索引:(a, b, c)
WHERE a = 1                  ✅ 用到 a(全值匹配)
WHERE a = 1 AND b = 2        ✅ 用到 a, b
WHERE a = 1 AND b = 2 AND c = 3  ✅ 用到 a, b, c(全覆盖)
WHERE a = 1 AND c = 3        ✅ 用到 a(c 用不到,中间跳过了 b)
WHERE b = 2                  ❌ 不走索引(跳过了 a)
WHERE b = 2 AND c = 3        ❌ 不走索引(跳过了 a)
WHERE a LIKE 'abc%'          ✅ 用到 a(前缀匹配)
WHERE a LIKE '%abc'          ❌ a 失效(后缀匹配)

-- 范围查询后面的列失效
WHERE a = 1 AND b > 2 AND c = 3   ✅ a, b 用到,c 用不到(b 是范围,c 无法确定顺序)
sql

关于 WHERE 子句字段顺序: MySQL 优化器会自动调整查询条件的顺序以匹配索引,所以 WHERE b=2 AND a=1WHERE a=1 AND b=2 效果相同(如果有联合索引 (a,b))。 但面试中考察的是索引列是否被包含,而不是 SQL 中的书写顺序。

面试回答(2分钟版)

最左前缀原则是联合索引的核心使用规则。以联合索引 (a,b,c) 为例,B+ 树的叶子节点先按 a 排序,a 相同时按 b 排序,b 相同时再按 c 排序,所以索引只有从最左列开始连续匹配才能生效。具体来说,WHERE a=1 可以用到 a,WHERE a=1 AND b=2 可以用到 a 和 b,WHERE a=1 AND b=2 AND c=3 三列全部命中。但如果跳过了中间列,比如 WHERE a=1 AND c=3,只能用到 a,c 无法走索引因为中间缺了 b 的排序就不连续了。同理 WHERE b=2 完全不走索引因为跳过了最左列 a。还有一个重要规则是范围查询后的列会失效,比如 WHERE a=1 AND b>2 AND c=3,a 和 b 都能用到索引,但 b 是范围查询,在 b 的范围内 c 的排序不再有序,所以 c 用不到索引。需要注意的是 SQL 中 WHERE 子句字段的书写顺序不影响索引使用,MySQL 优化器会自动调整顺序来匹配索引,面试考察的是条件中是否包含了对应的索引列。

追问与易错

追问方向:

  • “WHERE a=1 AND b>2 AND c=3 能用索引 (a,b,c) 的哪些列?”→ 能用到 a 和 b,c 用不到;因为 b 是范围查询,在 b 的范围内 c 的排序不再有序,无法通过索引定位;但 ICP 优化可在索引层过滤 c
  • “ORDER BY 也遵循最左前缀吗?”→ 是的,ORDER BY 要利用索引排序也需满足最左前缀;如索引 (a,b,c),WHERE a=1 ORDER BY b,c 可走索引排序,但 ORDER BY b,c 跳过 a 则触发 filesort
  • “覆盖索引和最左前缀什么关系?”→ 两者独立但常配合使用;最左前缀决定索引能否用于 WHERE 过滤,覆盖索引决定是否需要回表;联合索引 (a,b,c) 查 SELECT b,c WHERE a=1 既满足最左前缀又覆盖查询字段

易错点:

  • ❌ WHERE 顺序必须和索引顺序一致——优化器会调整
  • ❌ 范围查询完全不能用索引——范围列本身可以用