查询在UNION之前或之后加入的性能

Dan*_*Dan 4 sql t-sql sql-server

假设我们有一个查询基本上使用union来将2个记录集合并为1.现在,我需要通过使用连接来复制记录.我认为选项1在我看来是出于性能原因最好的选择,但我想知道SQL查询专家的想法.

基本上,我"知道"答案是"1".但是,我也想知道,我可能是错的 - 我可能会错过这方面的一面吗?

(SQL Server)以下是我的选择.

伪代码

原始查询:

Select Name, Category from t1
Union
Select Name, Category from t2
Run Code Online (Sandbox Code Playgroud)

选项1)

Select Name, Category from t1
Inner Join (here)
Union
Select Name, Category from t2
Same inner Join (here)
Run Code Online (Sandbox Code Playgroud)

选项2)

Select * from (
Select Name, Category from t1
Union
Select Name, Category from t2
) t
(Inner Join Here)
Run Code Online (Sandbox Code Playgroud)

Qua*_*noi 5

SELECT  Name, Category
FROM    t1
JOIN    t_right
ON      right_category = category
UNION
SELECT  Name, Category
FROM    t2
JOIN    t_right
ON      right_category = category

SELECT  *
FROM    (
        SELECT  Name, Category
        FROM    t1
        UNION
        SELECT  Name, Category
        FROM    t2
        ) t
JOIN    t_right
ON      right_category = category
Run Code Online (Sandbox Code Playgroud)

这些查询不相同:如果右表中的两个以上记录可以满足连接条件,则第二个查询可以返回重复项,如下所示:

t1

Name   Category
---    ---
Apple  1


t2

Name   Category
---    ---
Apple  1

t_right

Category
---
1
1
Run Code Online (Sandbox Code Playgroud)

第一个查询将返回Apple, 1一次,第二个查询将返回两次.

在性能方面,在我们看到您的数据之前,很难确定哪个查询会更有效:

  • 第一个选项可以通过对每个查询应用不同的算法来提高效率.

  • 第二个选项可以通过只读一次右表来提高效率.

根据经验,一个很粗略的规则,如果连接条件是选择第一个选项会更有效率t1t2,而第二个选项将是更有效的,如果它不是.

但是,在简单的情况下(在具有很少高基数值的sargable条件下SQL Server的连接),优化器会将连接推出子查询,以便它与以下查询相同:

SELECT  Name, Category
FROM    t_right
CROSS APPLY
        (
        SELECT  Name, Category
        FROM    t1
        WHERE   t1.Category = t_right.category
        UNION
        SELECT  Name, Category
        FROM    t2
        WHERE   t2.Category = t_right.category
        ) t
Run Code Online (Sandbox Code Playgroud)