最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
为什么MySQL在执行UNION操作时建议使用UNION ALL
时间:2026-07-04 10:37:46 编辑:袖梨 来源:一聚教程网
UNION ALL 性能远高于 UNION,因其不执行去重和隐式排序,避免临时表与文件排序;UNION 等价于 UNION ALL 后加 DISTINCT,触发 Using temporary 和 Using filesort,导致 I/O 与 CPU 开销剧增,且结果行数和顺序不可控。
UNION ALL 比 UNION 快得多,因为不触发去重逻辑
MySQL 执行 UNION 时,会隐式做两件事:先合并所有子查询结果,再对整个结果集去重(等价于加了 DISTINCT),这通常意味着排序或哈希扫描;而 UNION ALL 就是把各分支结果直接拼起来,不碰数据内容。实测中,两个各返回 50 万行的子查询,UNION ALL 可能在 200ms 内流式返回,UNION 却卡在 Using temporary; Using filesort 上,耗时数秒甚至 OOM。
常见错误现象包括:
- 执行计划里出现
Using temporary或Using filesort - 查询响应时间随结果集增长非线性飙升
- 临时表空间(
tmp_table_size/max_heap_table_size)被频繁打满
UNION 会悄悄改掉你的结果行数和顺序
只要任意两行在所有列上完全相等,UNION 就会干掉一个——哪怕它们来自不同业务含义的表(比如「正式员工」和「外包人员」都叫张三、部门相同),也会被当成重复行过滤掉。这不是 bug,是设计行为。
更隐蔽的是顺序问题:UNION 去重过程通常伴随隐式排序(尤其 MySQL 8.0 以前),导致结果顺序不可控;而 UNION ALL 至少能保持各子查询的原始输出顺序(除非你显式加 ORDER BY)。
使用场景举例:
- 合并按天分表的日志(
log_20260501,log_20260502…)→ 不需要去重,用UNION ALL - 跨库汇总用户注册数 → 各库 ID 独立,不可能重复,用
UNION ALL - 补全缺失维度值(如左连接后用
UNION ALL加默认分类)→ 明确要保留所有行
列对齐、类型兼容、ORDER BY 写法必须严格按规则来
UNION 和 UNION ALL 都不是“智能拼接”,它们只认位置,不认字段名。下面这些写法都会报错:
-
SELECT name, id FROM t1 UNION SELECT id, name FROM t2→ 列顺序错,第一列是t1.name和t2.id拼的,语义混乱 -
SELECT created_at FROM orders UNION SELECT order_time FROM history→ 类型不兼容(比如DATETIMEvsTIMESTAMP在某些版本会失败) -
SELECT x FROM a ORDER BY x LIMIT 10 UNION SELECT y FROM b ORDER BY y LIMIT 10→ 语法非法,MySQL 直接抛ERROR 1221
正确做法:
- 统一用
CAST()或CONVERT(... USING utf8mb4)显式转类型 - 所有子查询列数、顺序、别名必须一致,例如都写成
SELECT id AS uid, name AS fullname FROM ... -
ORDER BY只能放在最后,且只能引用列名或位置序号:... UNION ALL ... ORDER BY fullname - 想各自取 top N?包一层子查询:
(SELECT ... ORDER BY x LIMIT 10) UNION ALL (SELECT ... ORDER BY y LIMIT 10)
什么时候真该用 UNION?别靠感觉判断
只有当以下**全部满足**时,才考虑 UNION:
- 业务逻辑明确要求结果中每行全局唯一(比如合并多个来源的用户 ID,且 ID 是主键)
- 你无法在子查询里通过
WHERE或JOIN提前排重 - 数据量不大,或已确认去重开销可控(比如总行数
如果只是“怕有重复所以保险起见”,那反而容易埋坑——比如某天上游数据逻辑变更,导致本不该去重的行被意外合并,问题很难回溯。更稳妥的做法是:先用 UNION ALL 查出全量,再用 SELECT DISTINCT 包一层(虽然性能略差,但语义清晰、可调试)。
最容易被忽略的一点:即使两个表结构一模一样,UNION 也会把 NULL 和 NULL 当作相等去重——而很多业务场景里,NULL 的语义是“未知”,不是“相同”。这点在统计类查询中极易引发偏差。
相关文章
- 高德地图路线规划显示异常怎么办 07-09
- 漫蛙漫画官方版正版ios如何安装 07-09
- 胖东来官网地址-胖东来官方网站入口地址 07-09
- investopedia官网中文版入口-investopedia国内能用的官方网页版入口地址 07-09
- 一点文学txt小说网站入口-一点文学小说官网入口地址2026最新 07-09
- 易校园怎么绑定微信 07-09