Mysql 数据库使用入门系列:复合索引和单(字段)索引优缺点(四)
- 作者: 刘杰
- 来源: 技术那些事
- 阅读:98
- 发布: 2025-07-27 06:50
- 最后更新: 2025-07-27 12:13
之前文章,已经深入讲解了,如何对 Mysql 查询的优化,如何调整索引才能完美适配 sql 业务查询。今天我们更加深入的聊一聊,单字段索引和复合索引的优缺点,以便在后续工作中能够合理的选择索引类型,让业务查询更上一层楼。
首先假设有 MySQL 中的某个数据表,其有 a、b、c 三个字段。在 a、b、c 三个字段分别建立单独索引(单字段索引),与建立一个复合索引(如(a,b,c)
),其实是各有适用场景。没有绝对的 “更好”,其核心差异体现在查询适配性、性能开销和维护成本上。下面让我们分别从三个维度分析一下利弊:
一、单字段索引(a、b、c 分别建索引)
优点:
-
适配单一字段查询
对仅涉及 a、仅涉及 b、仅涉及 c 的查询(如
WHERE b=?
),单字段索引能直接生效,而复合索引(a,b,c
)因 “最左前缀原则”,无法匹配WHERE b=?
或WHERE c=?
这类跳过左前缀的查询。 -
索引选择更灵活
当查询包含多个条件(如
WHERE a=? AND b=?
)时,MySQL 优化器可能选择 “索引合并”(如同时使用 a 和 b 的单字段索引,取交集),尤其当某个单字段索引的选择性极高时,可能比复合索引更高效。 - 修改成本更低(针对部分字段) 若仅更新 a 字段,只需维护 a 的单字段索引;而复合索引需整体更新,在高频更新场景下,单字段索引的维护开销可能更低。
缺点:
-
多字段组合查询效率低
对
WHERE a=? AND b=? AND c=?
这类组合查询,单字段索引无法一次性过滤所有条件,可能需要 “索引合并”(intersection),但 MySQL 的索引合并效率较低(尤其数据量大时),远不如复合索引的 “一次定位”。 - 存储空间和维护成本高 三个单字段索引的总存储空间通常大于一个复合索引(每个索引都需单独存储 B + 树结构);且插入 / 删除数据时,需同步维护三个索引,写操作性能下降更明显。
-
无法实现覆盖索引(多字段场景)
若查询需要返回 a、b、c 之外的字段(如
SELECT d FROM t WHERE a=? AND b=?
),单字段索引无法覆盖,必须回表查询;而复合索引可通过包含更多字段实现覆盖(如(a,b,d)
)。
二、复合索引(如(a,b,c)
)
优点:
-
高效支持多字段组合查询
符合 “最左前缀原则” 的组合查询(如
WHERE a=?
、WHERE a=? AND b=?
、WHERE a=? AND b=? AND c=?
)均可直接利用复合索引,一次定位到符合条件的行,避免索引合并的开销。 - 节省存储空间,降低维护成本 一个复合索引的 B + 树结构比三个单字段索引更紧凑,总占用空间更小;写操作(插入 / 更新 / 删除)时只需维护一个索引,性能优于维护三个单字段索引。
-
支持覆盖索引,减少回表
若查询的字段都包含在复合索引中(如
SELECT a,b,c FROM t WHERE a=? AND b=?
),可直接从索引中获取数据,无需回表访问主键索引,大幅提升效率。 -
优化排序 / 分组操作
若查询包含
ORDER BY a,b,c
或GROUP BY a,b
,复合索引的顺序与排序 / 分组一致时,可避免 MySQL 的 “Using filesort”(临时表排序),直接利用索引顺序返回结果。
缺点:
-
对 “非左前缀” 查询无效
复合索引
(a,b,c)
无法支持WHERE b=?
、WHERE b=? AND c=?
等不包含最左字段 a 的查询,这类场景下只能走全表扫描或依赖其他单字段索引。 -
字段顺序固定,适配性有限
若业务查询中
b
单独出现的频率远高于a
,但复合索引以a
为前缀,则无法高效支持b
的查询,灵活性不如单字段索引。 - 更新成本集中 若复合索引中的任一字段(如 a、b、c)被频繁更新,会导致整个复合索引的频繁维护,可能比单字段索引(仅更新对应字段索引)的开销更高。
三、如何选择?关键看查询模式
优先选复合索引的场景
- 业务中多字段组合查询频繁(如
a+b
、a+b+c
),且符合最左前缀顺序; - 单表索引数量已较多(需控制总数),或写操作(插入 / 更新)频繁(需减少索引维护成本);
- 需要利用覆盖索引优化查询(避免回表)。
优先选单字段索引的场景
- 业务中单一字段查询为主(如经常单独查 a、单独查 b),组合查询极少;
- 字段更新频率差异大(如 a 很少更新,b 频繁更新,单独建索引可降低 b 的维护成本);
- 组合查询的字段顺序不固定(如有时查
a+b
,有时查b+c
,复合索引难以覆盖)。
下面,我们来总结一下:
复合索引的优势是高效支持多字段组合查询、节省空间、降低整体维护成本,但依赖固定的字段顺序;
单字段索引的优势是适配单一字段查询、灵活性高,但在组合查询中效率低、维护成本高。
在我们工作中,实际更常见的是 “混合策略”:例如建立复合索引(a,b,c)
满足主要组合查询,同时对单独查询频繁的b
或c
补充单字段索引(需权衡总索引数量),最终通过EXPLAIN
分析查询计划验证效果。看是否能够保证查询效率。