什么是联合索引_mysql复合索引原理

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

联合索引(也叫复合索引)是 MySQL 中对两个或更多列共同建立的一个 B+ 树索引,它的核心作用是提升多条件查询的效率。它不是多个单列索引的简单叠加,而是一个整体结构——数据按索引列**从左到右依次排序**,就像电话簿先按姓氏、再按名字、最后按中间名排列一样。

联合索引的物理结构是怎样的

INDEX idx(a, b, c) 为例:

B+ 树的第一层按 a 列值整体排序 a 相同的记录中,第二层再按 b 排序 a 和 b 都相同的记录中,第三层再按 c 排序 叶子节点不仅存 a、b、c 的值,还包含对应行的主键(用于回表)

这种嵌套排序决定了:只有知道前面的列值,后面的列才能被高效定位。这也是“最左前缀原则”的底层原因。

最左前缀原则怎么起作用

查询能否用上联合索引,取决于 WHERE 条件是否构成索引列的**连续左前缀**:

✅ 可用:
a = ?
a = ? AND b = ?
a = ? AND b = ? AND c = ?
✅ 范围查询也支持:
a > ?
a = ? AND b > ?
a = ? AND b = ? AND c BETWEEN ? AND ?
❌ 无法使用:
b = ?
c = ?
a = ? AND c = ?
(跳过 b)、
b = ? AND c = ?

注意:MySQL 8.0.13+ 引入了索引跳跃扫描(Index Skip Scan),在第一列区分度很低(比如只有几个固定值)时,可能绕过最左限制使用索引,但这是优化器的主动选择,并非常规路径。

为什么列顺序特别关键

联合索引的列顺序直接影响哪些查询能走索引、以及索引的过滤效率:

高选择性列优先:比如用户表中
user_id
status
(如 0/1)区分度高得多,应放前面
等值查询列优先于范围查询列:例如
WHERE dept = 'tech' AND create_time > '2024-01-01'
,dept 应排在 create_time 前面
排序和分组字段可纳入考虑:如果常查
ORDER BY a, b
,联合索引
(a,b)
可避免额外排序

错误的顺序可能导致索引“建了却用不上”,比如

(create_time, category_id)
在按 category_id 精确查询时基本无效,换成
(category_id, create_time)
就能覆盖更多场景。

联合索引比多个单列索引更省又更有效

对比单独建

INDEX(a)
INDEX(b)
INDEX(c)

✅ 联合索引
(a,b,c)
可同时服务 a、a+b、a+b+c 查询,且只占一份存储空间
✅ 写入时只需维护一个索引结构,减少 INSERT/UPDATE/DELETE 的开销 ❌ 多个单列索引无法协同加速多条件查询(优化器通常只选其一),还会加剧磁盘和内存压力 ⚠️ 注意宽度:一般建议不超过 3 列,列太多会让索引页变大、树变深,反而降低效率

本质上,联合索引是对查询模式的精准建模——建得准,才压得住慢 SQL。

相关推荐