不能一概而论。联合索引仅在WHERE条件从左到右连续匹配最左前缀时生效,如(a,b,c)可加速a=1、a=1 AND b=2等,但对b=2或c=3无效;高频单字段查询仍需独立单列索引。

联合索引能代替单列索引吗?
不能一概而论。MySQL 的 WHERE 条件中,只有当查询条件**从左到右连续匹配**联合索引的最左前缀时,索引才会被有效使用。比如联合索引 (a, b, c) 可以加速 WHERE a = 1、WHERE a = 1 AND b = 2、WHERE a = 1 AND b = 2 AND c = 3,但对 WHERE b = 2 或 WHERE c = 3 完全无效。
所以如果你有高频查询 WHERE b = ?,单独建 (b) 索引仍是必要的——联合索引 (a, b, c) 并不“包含”对 b 的独立查找能力。
什么时候该用联合索引而不是多个单列索引?
当多个字段**经常一起出现在 WHERE、ORDER BY 或 GROUP BY 中**,且顺序稳定时,联合索引更高效。MySQL 5.6+ 虽支持索引下推(ICP)和松散索引扫描,但多个单列索引在多条件查询中通常只能用上一个(选区分度最高的那个),其余条件回表后过滤,IO 开销大。
-
WHERE status = 'active' AND created_at > '2024-01-01'→ 建(status, created_at)比两个单列索引更优 -
ORDER BY user_id, created_at DESC→ 联合索引可避免文件排序(Using filesort) - 单列索引过多会拖慢写入性能,每个 INSERT/UPDATE/DELETE 都要维护所有相关索引
联合索引字段顺序怎么排?
核心原则:**区分度高 + 经常用于等值查询的字段放左边,范围查询(>, BETWEEN, LIKE 'abc%')字段放右边,排序/分组字段尽量靠右但不能打断最左前缀匹配。**
例如用户表常见查询:WHERE tenant_id = ? AND status = ? AND created_at > ? ORDER BY id DESC。此时 (tenant_id, status, created_at) 是合理顺序,因为:
-
tenant_id通常是租户隔离字段,等值且高区分度,适合做最左列 -
status也是等值,放在第二位可继续利用索引 -
created_at > ?是范围查询,它之后的字段(如id)无法再用于索引查找,所以不建议把它放第三位后还指望ORDER BY id走索引;若真需避免filesort,可考虑(tenant_id, status, created_at, id),但注意该索引体积更大
EXPLAIN 看不出联合索引是否生效?
关键看 key 和 key_len 字段:
-
key显示用了哪个索引 → 确认没走错索引 -
key_len表示实际用到索引的字节数 → 对比索引定义可反推用了几列。比如utf8mb4字符串字段长度为 50,单列索引key_len最大为50 × 4 = 200;若联合索引(a INT, b VARCHAR(50)),查WHERE a = 1 AND b = 'x'时key_len应为4 + 200 = 204(INT 为 4 字节,VARCHAR 变长但等值匹配时按最大可能长度算) - 如果
key_len明显偏小(比如只显示 4),说明只用到了联合索引第一列,后面条件没走索引
容易忽略的一点:WHERE a = 1 OR b = 2 这类条件,即使 a 和 b 各有单列索引,MySQL 也大概率不会合并使用(除非开启 index_merge 且优化器认为划算),更别说联合索引了——这种场景往往需要重写逻辑或加冗余索引。









