mysql中联合索引的创建与使用方法

来源:这里教程网 时间:2026-02-28 20:45:44 作者:

联合索引字段顺序为什么不能随便调换

联合索引的字段顺序直接影响查询能否命中索引,本质是 B+ 树的排序规则决定的。MySQL 会按定义顺序逐列构建索引项,

(a, b, c)
的索引树先按
a
排序,
a
相同时再按
b
排序,
a,b
都相同时才按
c
排序。

这意味着只有满足「最左前缀匹配」的条件才能走索引:

WHERE a = 1
✅ 走索引
WHERE a = 1 AND b = 2
✅ 走索引
WHERE a = 1 AND b = 2 AND c = 3
✅ 走索引
WHERE b = 2
❌ 不走索引(跳过
a
WHERE a = 1 AND c = 3
⚠️ 只用到
a
c
无法利用(
b
缺失导致
c
无序)

如何创建高效联合索引:三个实操原则

建索引不是堆字段,而是围绕高频查询模式设计。常见误区是把所有 WHERE 字段全塞进去,结果索引大、更新慢、还用不上。

把等值查询字段放最左:例如
WHERE status = 'done' AND user_id = 123 AND created_at > '2024-01-01'
,应建
(status, user_id, created_at)
status
user_id
是等值,
created_at
是范围,放最后
高区分度字段优先但不绝对:比如
gender
(只有 'M'/'F')区分度极低,即使放最左也难提升效率;但如果查询总是
WHERE gender = 'F' AND city = 'Beijing'
,且
city
值太多,反而先筛
gender
能快速缩小扫描范围
避免冗余索引:已有
(a, b)
,再建
(a)
就是冗余;但
(a, b)
(a, b, c)
不冗余——后者支持三字段查询,前者不支持

验证联合索引是否生效:看
EXPLAIN
的关键字段

别只看

type
是否为
ref
range
,重点盯这三个输出:

key
:显示实际使用的索引名,为空说明没走索引
key_len
:表示用了索引的多少字节。例如
key_len = 10
对应
(a, b)
a
占 4 字节 +
b
占 6 字节,说明两列都用上了;若
key_len = 4
,大概率只用了
a
Extra
中出现
Using index
表示覆盖索引(无需回表),出现
Using where; Using index
是理想状态;若出现
Using filesort
Using temporary
,说明排序或分组没走索引,可能需要调整索引或 SQL
EXPLAIN SELECT * FROM orders WHERE status = 'shipped' AND user_id = 5566;

什么时候联合索引会“失效”:几个典型陷阱

即使语法正确、字段顺序合理,以下操作也会让联合索引退化为全表扫描或部分失效:

对索引字段做函数操作:
WHERE YEAR(created_at) = 2024
→ 改成
WHERE created_at >= '2024-01-01' AND created_at 
隐式类型转换:
user_id
INT
,但写成
WHERE user_id = '123'
(字符串),可能导致索引失效(取决于 MySQL 版本和字符集)
使用
OR
连接非同一索引字段:
WHERE a = 1 OR b = 2
,除非
a
b
分别有单列索引,否则联合索引
(a,b)
无法整体利用
LIKE 左模糊:
WHERE name LIKE '%abc'
无法用索引;
WHERE name LIKE 'abc%'
可以(前提是
name
在联合索引最左或连续前缀位置)

联合索引不是银弹,它的价值高度依赖查询写法和数据分布。上线前务必用真实数据量 +

EXPLAIN
验证,而不是只看测试库里几条记录的执行速度。

相关推荐