外观
一句话答案
联合索引 (a,b,c) 只有从最左列开始连续匹配才能走索引,跳过中间列或范围查询后的列无法使用索引。
核心要点
联合索引的底层结构: 索引 (a, b, c) 的 B+ 树叶子节点,数据先按 a 排序,a 相同时按 b 排序,b 相同时按 c 排序。
最左前缀原则: 查询条件必须从索引的最左列开始匹配,不能跳过中间列。
sql
-- 索引:(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 无法确定顺序)关于 WHERE 子句字段顺序: MySQL 优化器会自动调整查询条件的顺序以匹配索引,所以 WHERE b=2 AND a=1 与 WHERE a=1 AND b=2 效果相同(如果有联合索引 (a,b))。 但面试中考察的是索引列是否被包含,而不是 SQL 中的书写顺序。
追问与易错
追问方向:
- WHERE a=1 AND b>2 AND c=3 能用索引 (a,b,c) 的哪些列?
- ORDER BY 也遵循最左前缀吗?
- 覆盖索引和最左前缀什么关系?
易错点:
- ❌ WHERE 顺序必须和索引顺序一致——优化器会调整
- ❌ 范围查询完全不能用索引——范围列本身可以用
💡 记忆锚点
联合索引 (a,b,c) 像一本按"省-市-区"排序的地址簿:你可以查"北京"、"北京-朝阳"、"北京-朝阳-三里屯",但不能直接查"朝阳"(跳过了省)。范围查询像说"北京-朝阳到海淀",之后的"区"就不确定顺序了。注意:SQL 中 WHERE 字段的书写顺序无所谓,优化器会自动调整。