SQL中UNION和UNION ALL的区别详解

173 阅读4分钟

很高兴你能来阅读,过去一年多,我主要从事天猫国际商品以及订单相关数仓开发与数据分析工作。接下来会陆续分享这段经历中的实战问题、对应解决思路,以及数仓基础的进阶学习总结,希望能给有需要的朋友带来参考和帮助~

在 SQL 中,UNIONUNION ALL 都是用于合并多个 SELECT 语句的结果集,但核心区别集中在去重逻辑性能上,以下是详细拆解:

image.png

一、核心区别(最关键)

特性UNIONUNION 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语句结果的“拼接顺序”,完全遵循原始数据的排列。

三、示例演示

假设有两张表 t1t2

-- 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——既浪费性能,又可能因默认排序导致结果顺序不符合预期。