SQL 复合索引的最左前缀原则详解

13次阅读

复合索引遵循最左前缀原则:mysql只能从联合索引最左列开始连续匹配查询条件,中间不可跳过或倒序;因B+树按索引列顺序全局排序,缺失首列则无法定位起始位置,导致全表扫描。

SQL 复合索引的最左前缀原则详解

复合索引的最左前缀原则,核心就一句话:MySQL 只能从联合索引最左边的列开始,连续地匹配查询条件,中间不能跳过,也不能倒着来。

为什么必须从最左列开始?

因为联合索引底层是 B+ 树,数据按索引定义的顺序整体排序:先按第一列升序,该列值相同时再按第二列升序,以此类推。这意味着:

  • 第一列在整个索引中是全局有序的
  • 第二列只在第一列值相同的数据块内有序
  • 第三列只在前两列都相同的子块内有序

如果查询不带第一列(比如只查 age = 25),数据库无法定位起始位置——因为 age=25 的记录可能分散在不同 name 分支下,只能全表扫描。

哪些查询能用上 (a, 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 b > 2 → a 和 b 有效,c 不生效(范围查询后中断)
  • WHERE a = 1 ORDER BY b → a 用于过滤,b 用于排序,避免额外排序开销

哪些查询会让索引失效?

常见三类断点:

  • 跳过中间列:WHERE a = 1 AND c = 3 → b 缺失,c 无法定位,只有 a 生效
  • 不从最左开始:WHERE b = 2 或 WHERE b = 2 AND c = 3 → 完全不走索引
  • 前导模糊匹配:WHERE name LIKE ‘%三’ → 破坏最左顺序;而 WHERE name LIKE ‘张%’ 是有效的

联合索引字段顺序怎么定才合理?

不能只看单个字段区分度,得看实际查询模式:

  • 高频等值查询字段优先靠左(如 status、user_id)
  • 范围查询字段(>、
  • 常与等值条件组合的排序或分组字段,可顺势接在等值列之后(如 WHERE status = ? ORDER BY create_time)
  • 如果经常查 WHERE status = ‘paid’,那么 (status, user_id) 比 (user_id, status) 更高效

最终是否生效,一定要用 EXPLaiN 查看 key_lentype 字段验证,别凭感觉。

text=ZqhQzanResources