UNION自动去重并隐式排序,UNION ALL仅拼接、保留重复且不排序;前者性能低、后者速度快,大数据量优先选UNION ALL,需唯一性时才用UNION。

直接看效果:UNION 合并后自动去重+隐式排序,UNION ALL 只是拼接,保留重复、不排序、速度快。
结果是否去重
UNION 会把两个结果集中完全相同的行合并为一行,哪怕来自不同表或不同查询条件;UNION ALL 不做任何判断,原样堆叠所有记录。
- 比如两张表都查出 (1, '张三'),UNION 返回一次,UNION ALL 返回两次
- 去重依据是整行字段值完全一致(包括 NULL),不是单个字段
- 如果业务上明确不需要去重(如日志归档、增量数据合并),优先选 UNION ALL
执行速度与资源消耗
UNION 要额外走排序 + 去重流程,底层常依赖临时表和哈希/树结构比对;UNION ALL 直接流式输出,基本不触发临时表。
- 百万级数据下,UNION 可能比 UNION ALL 慢 30%–50%,内存和 CPU 占用更高
- 在 ETL 或报表宽表构建中,90% 场景建议默认用 UNION ALL,仅当确认需唯一性时再换 UNION
- UNION 对 TEXT 类型字段支持不稳定,UNION ALL 无此限制
返回顺序是否可控
UNION 会强制按 SELECT 列顺序做一次隐式排序,可能打乱原始插入或查询顺序;UNION ALL 完全保持各子查询的自然输出顺序(先查的在前,后查的在后)。
- 若依赖时间先后(如按时间分区的订单表合并),用 UNION ALL 更可靠
- 想控制最终顺序,必须显式加 ORDER BY——UNION 的隐式排序不可靠,也不可预测
- 多个 UNION ALL 子句间不自动重排,适合流式处理或预排序数据源
使用前提和兼容性
两者都要求参与合并的每个 SELECT 的列数相同、对应列类型相容(如数值对数值、字符串对字符串),否则报错。
- 列名以第一个 SELECT 为准,后续 SELECT 的列名会被忽略
- 推荐给每个子查询加上别名或注释,避免字段错位引发逻辑错误
- UNION ALL 在大数据量、高并发场景更稳定,MySQL 源码层也对其做了更多优化路径










