LOGO 首页 OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 技术文档 其他文档  
 
网站管理员

索引合并不是万能药:MySQL同时用两个索引,为什么比不用还慢?

zhenglin
2026年9月9日 14:47 本文热度 141

某电商订单系统,开发人员给statuscreate_time分别建了单列索引。查询条件很简单:

SELECT * FROM orders 

WHERE status = 'PAID' AND create_time > '2026-09-01'

ORDER BY create_time DESC LIMIT 20;

EXPLAIN一看,possible_keys列显示两个索引,优化器选择了索引合并(Index Merge)Extra列出现Using intersect(idx_status, idx_create_time)

开发人员很高兴:“两个索引都用上了,优化器真智能!”

但实际跑起来,这条SQL在2000万数据的表上要3.8秒。加了个FORCE INDEX(idx_create_time)强制走单个索引,反而降到了0.3秒

优化器“智能”地做了错误的决定

今天把索引合并这件事彻底拆开,讲清楚它是什么、什么时候该用、什么时候千万别用。


一、索引合并的三种类型

MySQL的索引合并优化(Index Merge Optimization)在5.0时代就引入了,官方文档把它描述为一种“优化策略”,但不是“最优策略”。

1. Intersection(交集合并)

同时使用多个索引,取结果集的交集。

SELECT * FROM orders 

WHERE user_id = 12345 AND status = 'PAID';

如果user_idstatus各自有单列索引,优化器可能同时扫描两个索引,然后取交集。

2. Union(并集合并)

同时使用多个索引,取结果集的并集。

SELECT * FROM orders 

WHERE user_id = 12345 OR status = 'PAID';

这是最危险的一种——两个索引的结果集取并集,需要去重、排序,代价极高。

3. Sort-Union(排序并集合并)

先对索引扫描结果排序,再去重合并。比普通Union多了排序步骤,代价更高。

一个设计良好的复合索引通常比索引合并更高效,因为单次索引查找就能定位数据,避免了合并开销


二、索引合并的代价到底在哪?

索引合并看起来“利用了多个索引”,但代价隐藏在三个地方:

代价1:多次索引扫描 + 结果集合并

索引合并需要扫描多个索引树,然后把结果集在内存中做交集或并集运算。如果每个索引扫描返回的数据量都很大,合并操作本身的开销可能超过全表扫描。

代价2:随机I/O放大

索引扫描返回的是主键值(二级索引),然后需要回表读取完整行数据。索引合并意味着多次回表——每次索引扫描都要回表一次,I/O次数成倍增加。

代价3:基数估算偏差

优化器决定是否使用索引合并,依赖于基数估算(Cardinality Estimation)。如果统计信息过期或数据分布倾斜,优化器可能错误地认为索引合并很快,但实际上慢得要命。


三、3个真实踩坑场景

坑1:OR条件导致索引合并UNION,代价远超预期

SELECT * FROM orders 

WHERE user_id = 12345 OR create_time > '2026-01-01';

优化器可能选择索引合并UNION——分别扫描idx_user_ididx_create_time,然后合并去重。

但如果user_id=12345有10万行,create_time > '2026-01-01'有50万行,合并去重要处理60万行数据——比全表扫描还慢。

坑2:索引合并的基数估算偏差

MySQL优化器基于统计信息做决策。当统计信息过期时,优化器可能低估某个索引返回的行数,从而错误地选择索引合并方案。

坑3:多个单列索引 vs 一个复合索引

很多人有个误区:给每个查询条件列都建一个单列索引,让优化器自己去“合并”。

复合索引通常比索引合并更高效——索引合并需要扫描多个索引、合并结果集、去重、排序;复合索引一次扫描就能定位到目标行。

-- 不推荐:两个单列索引让优化器去合并

CREATE INDEX idx_user_id ON orders(user_id);

CREATE INDEX idx_status ON orders(status);


-- 推荐:一个复合索引覆盖查询

CREATE INDEX idx_user_status ON orders(user_id, status);


四、什么时候该用索引合并,什么时候该用复合索引?

场景推荐方案原因
查询条件是AND,各条件选择性都很高复合索引一次索引查找定位,无合并开销
查询条件是AND,但其中一个条件选择性极低单列索引+过滤复合索引收益有限,索引合并代价高
查询条件是OR,各条件选择性都很高索引合并UNION可接受无法用单个复合索引覆盖OR条件
查询条件是OR,但结果集很大改写SQL或用UNION ALL避免索引合并的去重和排序开销
查询条件经常变化,无法预建复合索引索引合并作为兜底聊胜于无,但需监控性能

五、怎么判断优化器是否选错了?

方法一:对比执行计划

分别用FORCE INDEX强制走单个索引和让优化器自由选择,对比响应时间。


方法二:查看EXPLAINExtra

  • Using intersect(...) → 交集合并,通常AND条件触发

  • Using union(...) → 并集合并,通常OR条件触发

  • Using sort_union(...) → 排序并集合并,代价最高

方法三:用EXPLAIN ANALYZE看实际行数

EXPLAIN ANALYZE会输出每个步骤的实际执行行数。如果actual rows远大于优化器估算的rows,说明基数估算有偏差。

方法四:使用OPTIMIZER_TRACE

开启optimizer_trace,可以看到优化器在索引合并和其他方案之间的代价对比,精确了解优化器为什么选了索引合并。


六、小结

索引合并是优化器的“兜底方案”,不是“首选方案”。能用复合索引解决的,优先用复合索引。如果EXPLAIN里出现了Using intersectUsing union,先确认索引合并的真实代价——很多时候,一个设计良好的复合索引比索引合并快一个数量级。索引合并的出现往往暗示你的索引设计还有优化空间。


阅读原文:点击这里


该文章在 2026/9/9 14:47:43 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-2  粤公网安备44030602007207号