UNION
和 和有什么不一样UNION ALL
?
22 回答
UNION
删除重复记录(结果中的所有列都相同),UNION ALL
不删除。
使用UNION
instead of时会降低性能UNION ALL
,因为数据库服务器必须做额外的工作来删除重复的行,但通常您不希望重复(尤其是在开发报表时)。
要识别重复项,记录必须是可比较的类型以及兼容的类型。这将取决于 SQL 系统。例如,系统可能会截断所有长文本字段以制作短文本字段以进行比较(MS Jet),或者可能拒绝比较二进制字段(ORACLE)
联合示例:
SELECT 'foo' AS bar UNION SELECT 'foo' AS bar
结果:
+-----+
| bar |
+-----+
| foo |
+-----+
1 row in set (0.00 sec)
UNION ALL 示例:
SELECT 'foo' AS bar UNION ALL SELECT 'foo' AS bar
结果:
+-----+
| bar |
+-----+
| foo |
| foo |
+-----+
2 rows in set (0.00 sec)
UNION 和 UNION ALL 都连接两个不同 SQL 的结果。它们在处理重复项的方式上有所不同。
UNION 对结果集执行 DISTINCT,消除任何重复的行。
UNION ALL 不会删除重复项,因此它比 UNION 更快。
注意:使用此命令时,所有选定的列都需要具有相同的数据类型。
示例:如果我们有两个表,1) Employee 和 2) Customer
- 员工表数据:
- 客户表数据:
- UNION 示例(它删除所有重复记录):
- UNION ALL 示例(它只是连接记录,而不是消除重复,因此它比 UNION 更快):
UNION
删除重复项,而UNION ALL
没有。
为了去除重复,必须对结果集进行排序,这可能会对 UNION 的性能产生影响,具体取决于被排序的数据量,以及各种 RDBMS 参数的设置(对于 Oracle 来说PGA_AGGREGATE_TARGET
,带有WORKAREA_SIZE_POLICY=AUTO
orSORT_AREA_SIZE
和SOR_AREA_RETAINED_SIZE
if WORKAREA_SIZE_POLICY=MANUAL
)。
基本上,如果可以在内存中进行排序,排序会更快,但同样需要注意数据量。
当然,如果您需要返回没有重复的数据,那么您必须使用 UNION,具体取决于数据的来源。
我会在第一篇文章中发表评论以限定“性能低得多”的评论,但没有足够的声誉(积分)来这样做。
在 ORACLE 中:UNION 不支持 BLOB(或 CLOB)列类型,UNION ALL 支持。
UNION 和 UNION ALL 之间的基本区别是联合操作从结果集中消除重复的行,但联合所有在加入后返回所有行。
来自http://zengin.wordpress.com/2007/07/31/union-vs-union-all/
UNION
命令用于从两个表
中UNION
选择相关信息,很像JOIN
命令。但是,使用该UNION
命令时,所有选定的列都需要具有相同的数据类型。使用UNION
,仅选择不同的值。
UNION ALL命令与
命令相同,除了选择所有值。UNION ALL
UNION
UNION ALL
Union
和之间的区别在于Union all
它Union all
不会消除重复的行,它只是从适合您的查询细节的所有表中提取所有行并将它们组合到一个表中。
UNION
语句有效地SELECT DISTINCT
对结果集执行a 。如果您知道返回的所有记录在您的联合中都是唯一的,请UNION ALL
改用它,它会提供更快的结果。
通过运行如下查询,您可以避免重复并且仍然比 UNION DISTINCT(实际上与 UNION 相同)运行得更快:
SELECT * FROM mytable WHERE a=X UNION ALL SELECT * FROM mytable WHERE b=Y AND a!=X
注意AND a!=X
部分。这比 UNION 快得多。
在这里的讨论中添加我的两分钱:可以将UNION
运算符理解为纯的、面向 SET 的 UNION - 例如 set A={2,4,6,8}, set B={1,2,3,4 }, A UNION B = {1,2,3,4,6,8}
在处理集合时,您不希望数字 2 和 4 出现两次,因为元素要么在集合中,要么不在集合中。
但是,在 SQL 的世界中,您可能希望将两个集合中的所有元素放在一个“包”{2,4,6,8,1,2,3,4} 中。为此,T-SQL 提供了运算符UNION ALL
.
UNION - 产生不同的记录
,而
UNION ALL - 产生包括重复在内的所有记录。
两者都是阻塞运算符,因此我个人更喜欢随时使用 JOINS 而不是阻塞运算符(UNION、INTERSECT、UNION ALL 等)。
为了说明为什么 Union 操作与 Union All 相比表现不佳,请查看以下示例。
CREATE TABLE #T1 (data VARCHAR(10))
INSERT INTO #T1
SELECT 'abc'
UNION ALL
SELECT 'bcd'
UNION ALL
SELECT 'cde'
UNION ALL
SELECT 'def'
UNION ALL
SELECT 'efg'
CREATE TABLE #T2 (data VARCHAR(10))
INSERT INTO #T2
SELECT 'abc'
UNION ALL
SELECT 'cde'
UNION ALL
SELECT 'efg'
以下是 UNION ALL 和 UNION 操作的结果。
UNION 语句有效地对结果集执行 SELECT DISTINCT。如果您知道返回的所有记录在您的联合中都是唯一的,请改用 UNION ALL,它会提供更快的结果。
使用 UNION 会导致执行计划中的不同排序操作。证明该陈述的证明如下所示:
不确定哪个数据库很重要
UNION
并且UNION ALL
应该适用于所有 SQL Server。
你应该避免不必要UNION
的 s 它们是巨大的性能泄漏。作为经验法则,UNION ALL
如果您不确定要使用哪个,请使用。
union 用于从两个表中选择不同的值,其中 union all 用于选择所有值,包括表中的重复值
(来自 Microsoft SQL Server 联机丛书)
联合[全部]
指定要组合多个结果集并作为单个结果集返回。
全部
将所有行合并到结果中。这包括重复项。如果未指定,则删除重复的行。
UNION
将花费太长时间,因为DISTINCT
在结果中应用了类似的重复行。
SELECT * FROM Table1
UNION
SELECT * FROM Table2
相当于:
SELECT DISTINCT * FROM (
SELECT * FROM Table1
UNION ALL
SELECT * FROM Table2) DT
应用结果的副作用是
DISTINCT
对结果进行排序操作。
UNION ALL
结果将显示为结果的任意顺序但UNION
结果将显示为ORDER BY 1, 2, 3, ..., n (n = column number of Tables)
应用于结果。当您没有任何重复行时,您可以看到此副作用。
我添加一个例子,
UNION,它正在与 distinct --> 更慢,因为它需要比较(在 Oracle SQL developer 中,选择查询,按 F10 键查看成本分析)。
UNION ALL,它在没有不同的情况下合并 --> 更快。
SELECT to_date(sysdate, 'yyyy-mm-dd') FROM dual
UNION
SELECT to_date(sysdate, 'yyyy-mm-dd') FROM dual;
和
SELECT to_date(sysdate, 'yyyy-mm-dd') FROM dual
UNION ALL
SELECT to_date(sysdate, 'yyyy-mm-dd') FROM dual;
UNION
将两个结构兼容的表的内容合并到一个组合表中。
- 不同之处:
UNION
和之间的区别在于UNION ALL
省略UNION will
重复记录而UNION ALL
将包括重复记录。
Union
结果集按升序排序,而UNION ALL
结果集未排序
UNION
对其结果集执行 a DISTINCT
,因此它将消除任何重复的行。而UNION ALL
不会删除重复项,因此它比UNION
.*
注意: 的性能UNION ALL
通常会优于UNION
,因为UNION
需要服务器执行删除任何重复项的额外工作。因此,如果确定不会有任何重复,或者重复不是问题,UNION ALL
出于性能原因,建议使用。
假设你有两张表Teacher & Student
两者都有4 列具有不同的名称,像这样
Teacher - ID(int), Name(varchar(50)), Address(varchar(50)), PositionID(varchar(50))
Student- ID(int), Name(varchar(50)), Email(varchar(50)), PositionID(int)
您可以为这两个具有相同列数的表应用 UNION 或 UNION ALL。但它们有不同的名称或数据类型。
当您UNION
对 2 个表应用操作时,它会忽略所有重复条目(表中行的所有列值与另一个表相同)。像这样
SELECT * FROM Student
UNION
SELECT * FROM Teacher
结果将是
当您UNION ALL
对 2 个表应用操作时,它会返回所有具有重复项的条目(如果 2 个表中一行的任何列值之间存在任何差异)。像这样
SELECT * FROM Student
UNION ALL
SELECT * FROM Teacher
表现:
显然UNION ALL的性能比UNION更好,因为它们会执行额外的任务来删除重复值。您可以在MSSQL上按ctrl+L从Execution Estimated Time中检查
我还想补充一件事——
Union :- 结果集按升序排序。
联合所有:- 结果集未排序。两个查询输出只是被附加。
UNION 和 UNION ALL 用于组合两个或多个查询结果。
UNION 命令从两个表中选择不同的和相关的信息,这将消除重复的行。
另一方面,UNION ALL 命令从两个表中选择所有值,显示所有行。
UNION 会删除重复记录,而 UNION ALL 则不会。但是需要检查将要处理的大量数据,并且列和数据类型必须相同。
由于联合在内部使用“不同”行为来选择行,因此在时间和性能方面成本更高。像
select project_id from t_project
union
select project_id from t_project_contact
这给了我 2020 年的记录
在另一方面
select project_id from t_project
union all
select project_id from t_project_contact
给了我超过 17402 行
从优先级的角度来看,两者具有相同的优先级。
如果没有ORDER BY
, aUNION ALL
可能会在执行过程中将行带回,而 aUNION
会让您等到查询的最后一刻再一次为您提供整个结果集。这可以在超时情况下产生影响 - aUNION ALL
保持连接处于活动状态。
因此,如果您有超时问题,并且没有排序,并且重复不是问题,UNION ALL
可能会很有帮助。
重要的!Oracle 和 Mysql 之间的区别:假设 t1 t2 它们之间没有重复的行,但它们有单独的重复行。示例:t1 有 2017 年的销售额,t2 有 2018 年的销售额
SELECT T1.YEAR, T1.PRODUCT FROM T1
UNION ALL
SELECT T2.YEAR, T2.PRODUCT FROM T2
在 ORACLE UNION ALL 中,从两个表中获取所有行。在 MySQL 中也会发生同样的情况。
然而:
SELECT T1.YEAR, T1.PRODUCT FROM T1
UNION
SELECT T2.YEAR, T2.PRODUCT FROM T2
在ORACLE中,UNION 从两个表中获取所有行,因为 t1 和 t2 之间没有重复值。另一方面,在MySQL中,结果集的行数会更少,因为在表 t1 和表 t2 中都会有重复的行!
UNION ALL
也适用于更多的数据类型。例如,当尝试联合空间数据类型时。例如:
select a.SHAPE from tableA a
union
select b.SHAPE from tableB b
会抛出
The data type geometry cannot be used as an operand to the UNION, INTERSECT or EXCEPT operators because it is not comparable.
然而union all
不会。