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