很高兴你能来阅读,过去一年多,我主要从事天猫国际商品以及订单相关数仓开发与数据分析工作。接下来会陆续分享这段经历中的实战问题、对应解决思路,以及数仓基础的进阶学习总结,希望能给有需要的朋友带来参考和帮助~
在 SQL 中,UNION 和 UNION ALL 都是用于合并多个 SELECT 语句的结果集,但核心区别集中在去重逻辑和性能上,以下是详细拆解:
一、核心区别(最关键)
| 特性 | UNION | UNION ALL |
|---|---|---|
| 去重逻辑 | 自动去除结果集中的重复行 | 保留所有行(包括重复行) |
| 排序操作 | 会对合并后的结果集做排序(为去重) | 无排序操作,按原始顺序合并 |
| 性能 | 较低(去重+排序消耗资源) | 较高(无额外操作,直接合并) |
| 适用场景 | 需确保结果集无重复的场景 | 已知无重复、或允许重复的场景 |
核心锚点:用“ALL”的字面意思破题
两者名称的唯一区别是“ALL”,而“ALL”在英文中是“全部、所有”的意思,这正是记忆的突破口,直接对应两者的核心差异:
- UNION ALL:带“ALL”,意味着“保留所有行”——包括多个结果集合并后产生的重复行,不做任何过滤,完全“照单全收”。
- UNION:不带“ALL”,意味着“要做筛选”——合并后会自动剔除重复行,只保留唯一的记录。
记忆口诀:“ALL带全,重复不删;UNION无全,去重把关”。
二、具体说明
1. 去重与排序(核心差异)
UNION 为了实现去重,会先将所有结果集合并,再对数据排序,最后删除重复的行;
UNION ALL 仅简单拼接多个结果集,不做任何去重或排序,因此重复行会被保留,且执行效率远高于 UNION。
2. 语法要求(两者一致)
无论使用 UNION 还是 UNION ALL,必须满足以下前提:
- 所有
SELECT语句的列数必须相同; - 对应列的数据类型必须兼容(可隐式转换);
- 列的顺序必须一致。
3. 性能差异:“多干活就慢,少干活就快”
性能差异是“是否去重”的直接结果:
- UNION:要去重,就必须先对合并后的所有数据进行“排序”(只有排序后才能快速识别重复行),这两个操作(排序+去重)都会消耗数据库资源,所以性能较低。
- UNION ALL:只做“简单拼接”,既不排序也不去重,相当于把多个结果集“直接粘在一起”,操作成本极低,所以性能较高。
联想记忆:UNION像“整理文件”——要把重复的文件删掉,得先按顺序排好再挑;UNION ALL像“堆叠文件”——不管内容是否重复,直接堆在一起,自然更快。
4. 排序差异:“去重必排序,无重不排序”
排序是UNION实现去重的“辅助操作”,并非独立特性,因此:
- UNION:默认会对结果集按列的自然顺序排序(目的是辅助去重),如果需要指定排序,可在最后一个SELECT后加ORDER BY。
- UNION ALL:不排序,结果集的顺序就是各个SELECT语句结果的“拼接顺序”,完全遵循原始数据的排列。
三、示例演示
假设有两张表 t1 和 t2:
-- t1 数据
id | name
1 | 张三
2 | 李四
-- t2 数据
id | name
2 | 李四
3 | 王五
1. UNION 示例(去重)
SELECT id, name FROM t1
UNION
SELECT id, name FROM t2;
结果(无重复行,且可能排序):
id | name
1 | 张三
2 | 李四
3 | 王五
2. UNION ALL 示例(保留重复)
SELECT id, name FROM t1
UNION ALL
SELECT id, name FROM t2;
结果(保留重复的“李四”,无排序):
id | name
1 | 张三
2 | 李四
2 | 李四
3 | 王五
四、性能建议
- 若能确定合并的结果集无重复(例如从不同业务维度查询、或通过 WHERE 条件过滤了重复),优先使用 UNION ALL,避免不必要的排序和去重开销;
- 仅当需要确保结果集唯一时,才使用
UNION(本质是UNION ALL + DISTINCT)。
实际开发中,90%以上的合并场景都适合用UNION ALL,除非明确需要去重,否则不要轻易用UNION——既浪费性能,又可能因默认排序导致结果顺序不符合预期。