最左前缀原则要求联合索引查询必须从最左列开始连续使用:如索引(name,age,dept),仅name、name+age、全列可用;跳过左列或断层则后续列失效;范围查询后列不参与查找但可能覆盖;排序分组也需满足该原则。

最左前缀原则是 MySQL 联合索引生效的核心规则:查询条件必须从联合索引的最左侧列开始,且连续使用,才能有效利用索引。
什么是联合索引的最左前缀
假设你创建了联合索引 INDEX idx_name_age_dept (name, age, dept),那么以下查询能用上该索引:
- WHERE name = '张三'(只用第1列)
- WHERE name = '张三' AND age = 25(用第1+2列)
- WHERE name = '张三' AND age = 25 AND dept = '技术部'(全列都用)
但这些写法无法使用该联合索引的全部能力:
- WHERE age = 25(跳过 name,索引失效)
- WHERE dept = '技术部'(只用最右列,不满足最左)
- WHERE name = '张三' AND dept = '技术部'(中间缺失 age,断层,dept 无法走索引)
等值查询 + 范围查询的边界要小心
在联合索引中,一旦出现范围查询(>、等),其右侧所有列都无法用于索引查找(但仍可用于索引覆盖)。
例如索引 (a, b, c):
- WHERE a = 1 AND b > 10 AND c = 5 → 只有 a 和 b 走索引查找,c 不参与查找(但若 SELECT 中只有 a/b/c,仍可能走覆盖索引)
- WHERE a > 1 AND b = 2 → 只有 a 走索引查找,b 完全失效(不能跳过 a 直接筛 b)
排序和分组也受最左前缀约束
ORDER BY 或 GROUP BY 要利用联合索引避免 filesort,也必须满足最左前缀:
- ORDER BY name, age ✅ 可走索引排序
- ORDER BY name ✅ 可走
- ORDER BY age ❌ 无法利用索引排序
- ORDER BY name, dept ❌ 中间跳过 age,dept 不连续,排序失效
注意:如果 WHERE 已经用到 name = ? AND age > ?,那 ORDER BY dept 就完全无法优化——因为 age 是范围,dept 已不在索引查找路径中。
如何设计更合理的联合索引顺序
把区分度高、经常用于等值过滤的列放左边;范围查询列尽量靠右;排序/分组字段若固定,可考虑放在最后(但需确保前面能走索引)。
常见策略:
- 高频等值条件列优先(如 user_id、status)
- 多个等值条件时,按查询频率或基数从高到低排(不一定严格,但有助于减少扫描行数)
- 把 ORDER BY 字段放在索引末尾,仅当前面所有列都能被 WHERE 充分过滤时才有效
- 避免冗余索引,比如已有 (a,b,c),通常无需再建 (a,b)










