联合索引生效需遵循最左前缀原则,即查询条件必须从索引最左列开始连续匹配,范围查询后右侧列失效,排序分组也须符合该顺序;设计时应按等值→范围→排序列顺序创建,并用EXPLAIN验证。
联合索引(也叫复合索引)在 MySQL 中是提升多条件查询性能的关键手段,但它的生效有明确规则,并不是只要建了就一定起作用。核心在于最左前缀原则——查询条件必须从索引的最左边列开始连续匹配,中间不能跳过。
比如你创建了联合索引 INDEX idx_name_age_dept (name, age, dept),它实际构建的是按 name 排序 → 在 name 相同下按 age 排序 → 在 name 和 age 都相同时按 dept 排序的 B+ 树。因此只有满足“从左到右连续”的查询条件才能走索引:
WHERE name = '张三' ✅ 走索引(只用第一列)WHERE name = '张三' AND age > 25 ✅ 走索引(用了前两列,age 可用于范围查找)WHERE name = '张三' AND age = 25 AND dept = '技术部' ✅ 全部命中WHERE age = 25 ❌ 不走索引(跳过了 name)WHERE name = '张三' AND dept = '技术部' ⚠️ 只能用上 name,dept 因为中间断开(缺少 age)无法利用索引排序,会回表或全扫 dept 部分一旦某列用了范围(>、、BETWEEN、LIKE 前缀不固定如 '%abc'),其右侧所有列都失效:
WHERE name = '张三' AND age > 25 AND dept = '技术部' → dept 列不生效WHERE name LIKE '张%' → 是范围,但属于最左列的“有效范围”,后续列仍可继续判断(因为 B+ 树中 '张%' 是连续区间)WHERE name LIKE '%张' → 不符合最左前缀,整个索引失效如果 SQL 中有 ORDER BY 或 GROUP BY,想避免 filesort,字段顺序必须和联合索引最左连续部分一致,且方向(ASC/DESC)要匹配(MySQL 8.0+ 支持混合方向,但老版本要求全部一致):
ORDER BY name, age ✅ 可利用 (name, age, dept)
ORDER BY age, dept ❌ 无法利用(没包含 name)ORDER BY name DESC, age ASC ❌ MySQL 5.7 默认不支持混合排序,会触发 filesort建索引前先看高频查询模式,优先把等值查询列放前面,再放范围列,最后放排序/分组列。例如常见查询是:WHERE status = ? AND create_time > ? ORDER BY update_time DESC,那就建 INDEX idx_status_time_update (status, create_time, update_time)。
(a,b,c) 就不用单独建 (a) 或 (a,b)
EXPLAIN 验证:重点看 key(是否命中)、key_len(用了索引多少字节,可反推用了几列)、Extra(有没有 Using where / Using index / Using filesort)