UNION 与 UNION ALL
比较去重和性能方面的差异,并了解为什么通常应使用 UNION ALL
UNION 与 UNION ALL 是 CoddyKit 上的免费 Coding Interview Prep 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Coding Interview Prep 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Coding Interview Prep 课程共包含 4 节课。
面试官为什么询问 UNION
集合运算会将一个结果集垂直堆叠到另一个结果集之上。UNION 和 UNION ALL 是面试官最先会采用的集合运算符,因为两者的区别只需一句话就能回答,却能体现您是否理解成本。
这个问题几乎总是这样表述的:“UNION 和 UNION ALL 有什么区别,应该使用哪一个?”优秀的回答会同时提到去重、排序和性能。
UNION 的作用
UNION 会将两个查询的行合并为一个结果集,然后删除重复行。只有每一列都相同的两行才算重复行。
为了删除重复行,执行引擎必须对所有合并后的行进行排序或哈希处理,这确实需要额外工作。从数学意义上说,UNION 返回的是一个集合:其中没有重复项。
SELECT city FROM customers
UNION
SELECT city FROM suppliers;UNION ALL 的作用
UNION ALL 会拼接两个结果集并保留每一行,包括重复行。它不进行去重,因此不会为了去重而排序或进行哈希处理。
由于跳过了去重步骤,UNION ALL 几乎总是更快;当您确定行不会重叠,或确实需要重复行时,它就是正确的选择。
SELECT city FROM customers
UNION ALL
SELECT city FROM suppliers;性能差异
面试中的核心结论是:UNION ALL 成本更低,因为它从不进行去重。UNION 必须将每个合并后的行与其他行进行比较,才能删除重复项。
UNION= UNION ALL + 一个隐式的 DISTINCT 步骤。- 对于大型结果集,这个 DISTINCT 步骤可能占据查询成本的主要部分。
如果不需要删除重复项,选择 UNION 就是在浪费 CPU 和内存。
包含重复项的示例
假设两个查询都可能返回行 'Paris'。使用 UNION 时,您会得到一个 Paris。使用 UNION ALL 时,您会得到两个 Paris。
面试官很喜欢让您预测行数。请始终先想象原始拼接结果,然后再问自己:这个运算符会删除重复项吗?
-- customers.city: Paris, Lyon
-- suppliers.city: Paris, Nice
-- UNION -> Paris, Lyon, Nice (3 rows)
-- UNION ALL -> Paris, Lyon, Paris, Nice (4 rows)重复项根据所有列定义
一个常见陷阱是:只有每个选定列都相等时,两行才算重复。只要添加一列不同的值,这两行就不再重复,因此 UNION 会保留它们。
这就是为什么在相同的表上,使用 UNION 时,SELECT id, city 通常比 SELECT city 返回更多行。
SELECT id, city FROM customers
UNION
SELECT id, city FROM suppliers;
-- ids differ -> few or no duplicates removed对合并结果排序
不能在各个分支上分别使用 ORDER BY;它作用于整个合并结果,并且必须在最后只出现一次。
面试官可能会问 ORDER BY 应该放在哪里。答案是:在最后一个查询之后使用一个 ORDER BY,并通过名称或位置引用输出列。
SELECT city FROM customers
UNION ALL
SELECT city FROM suppliers
ORDER BY city;列名来自第一个查询
在最终的 ORDER BY 中引用列时,请使用第一个 SELECT 中的名称(或别名)。第二个查询的列名会被忽略,不会用于标注输出。
当各分支为列使用了不同名称时,这一点很重要。请为第一个分支设置别名,以控制输出表头。
SELECT city AS location FROM customers
UNION ALL
SELECT town FROM suppliers
ORDER BY location;何时应选择 UNION
仅当确实可能存在重复行,并且您希望每个不重复的行只出现一次时,才使用 UNION。例如,合并两份联系人列表,其中同一人可能同时出现在两份列表中;或者从多个来源构建去重后的不重复值列表。
如果能够保证来源互不相交,UNION ALL 会得到相同结果,而且速度更快。
SELECT email FROM web_signups
UNION
SELECT email FROM store_signups;
-- one row per distinct email across both何时应选择 UNION ALL
当不会出现重复行、重复行具有实际意义,或者您之后要进行聚合时,请使用 UNION ALL。一个经典模式是堆叠互不包含相同行的月度分区表。
面试提示:请说明 UNION ALL 是默认选择,只有确实需要去重时才升级为 UNION。
SELECT * FROM sales_2023
UNION ALL
SELECT * FROM sales_2024;融会贯通
一份成熟的面试回答可以这样说:“UNION 会移除重复行,这会强制执行排序或哈希操作;UNION ALL 会保留所有内容,速度更快。两者都要求列数匹配且类型兼容,并且任何 ORDER BY 都只在末尾出现。我默认使用 UNION ALL,除非需要去重。”
这一句话同时体现了您对正确性和性能的认识。
快速检查
请检验您对 UNION 与 UNION ALL 区别的理解。
回顾
要点:
UNION= 合并并移除重复行(隐式 DISTINCT,额外开销)。UNION ALL= 合并并保留全部内容,速度更快,是合理的默认选择。- 重复行要求所有列都匹配。
- 单个
ORDER BY放在最末尾,并使用第一个查询的列名。
默认使用 UNION ALL;只有真正需要去重时才升级为 UNION。
常见问题解答
「UNION 与 UNION ALL」课时是免费的吗?
是的 — 「UNION 与 UNION ALL」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Coding Interview Prep 课程的其余内容,请升级到 CoddyKit PRO。 Coding Interview Prep 课程共包含 4 节课。
「UNION 与 UNION ALL」这节课中我会学到什么?
比较去重和性能方面的差异,并了解为什么通常应使用 UNION ALL 你通过在浏览器中直接运行的动手代码来练习 Coding Interview Prep,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Coding Interview Prep 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Coding Interview Prep 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「UNION 与 UNION ALL」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Coding Interview Prep 课中编写并运行代码吗?
能。每节 Coding Interview Prep 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- UNION 与 UNION ALL
- 列数与类型兼容性
- 使用 INTERSECT 和 EXCEPT 进行比较
- 使用连接模拟集合运算