首页/数据/SQL 速查/索引合并 index_merge
性能与执行计划72 条

索引合并 index_merge

OR 或多条件组合命中多个单列索引时,优化器可分别扫描再合并结果(Extra: Using intersect/union);它常提示单列索引需要组合成复合索引。

SQL 速查数据更新于 2026-10-13

索引合并是什么

当一条语句的多个条件分别能命中不同的单列索引时,MySQL 可以分别扫描再合并结果,这就是索引合并:AND 组合取交集,OR 组合取并集,EXPLAIN 的 Extra 里会显示 intersect 或 union。出现它往往是在提示:这几个单列索引更适合合成一个复合索引。

基本信息

intersect多个条件各自走索引后取交集,对应 AND 组合
union多个条件结果取并集,对应 OR 组合
成本特点合并需要排序去重,行数多时优化器可能放弃
复合索引更贴合查询的复合索引通常比合并更稳定
适用平台MySQL 特有优化手段,PostgreSQL 对 OR 的处理机制不同

典型使用场景

  • 排查 EXPLAIN 里出现的索引合并节点
  • 判断是否该把单列索引合并成复合索引
  • 对比 OR 改写与索引合并的效果
  • 验证索引合并是否真的更快
  • 优化多条件组合查询的执行计划

示例

示例
-- 跨列 OR 可能触发索引合并
EXPLAIN SELECT * FROM orders
WHERE user_id = 100 OR status = 'paid';
-- 可能输出:Using union(idx_user, idx_status); Using where

-- 屏蔽一侧索引,观察计划是否变化
EXPLAIN SELECT * FROM orders
WHERE user_id = 100 OR status = 'paid' IGNORE INDEX (idx_status);

-- 更稳的方案:建贴合查询的复合索引
ALTER TABLE orders ADD INDEX idx_user_status (user_id, status);

几种执行方式

方式对应条件代价来源
intersectAND 组合的多条件求交集后回表,行数估算不准会偏慢
unionOR 组合的多条件求并集需要排序去重
复合索引同一查询的多列条件一次范围扫描,通常更省
全表扫描优化器判断合并不划算简单但读行数多
看到 Using union 不代表优化到位:合并要额外排序去重,可以和复合索引方案、UNION 改写方案分别对比执行时间与读行数。
针对 OR 只加多个单列索引容易被误导:把常用的组合列建成复合索引,或改写 SQL,通常比依赖索引合并更可控。

易错点

  • 看到 Using union 就认为优化到位:合并有额外排序成本,要和复合索引或改写方案对比
  • 针对 OR 只加多个单列索引:复合索引或改写往往更可控,先评估查询形态
  • 以为索引合并一定比全表扫描快:行数多时求并集开销反而更大,用实测数据判断
  • 忽略合并对行数估算的依赖:估算偏差会让优化器时而合并时而不合并,计划不稳定
  • 在 PostgreSQL 里找同名机制:PG 对 OR 的处理方式不同,写优化方案前先确认目标库行为

数据来源与参考

  • MySQL 8.0 Reference Manual §8.2.1.3 Index Merge Optimization
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌