使用'where then Union'或使用'Union then Where'

shA*_*A.t 7 sql-server performance union rdbms query-performance

请记住这两种类型的查询:

--query1
Select someFields
From someTables
Where someWhereClues
Union all
Select someFields
FROM some Tables
Where someWhereClues

--query2
Select * FROM (
    Select someFields 
    From someTables
    Union all 
    Select someFields
    FROM someTables
    ) DT
Where someMixedWhereClues
Run Code Online (Sandbox Code Playgroud)

注意:
在两个查询中,最终结果字段都相同

我想到了第一个.查询更快或性能更好!
但经过一些研究后我对此笔记感到困惑:

SQL Server(作为RDBMS的示例)首先读取整个数据然后查找记录.=>所以在两个查询中所有记录都将读取和搜索.

请帮助我解决我的误解,以及query1和query2之间是否有任何其他差异?


编辑:添加样本计划:

select t.Name, t.type from sys.tables t where t.type = 'U'
union all
select t.Name, t.type from sys.objects t where t.type = 'U'

select * from (
    select t.Name, t.type from sys.tables t
    union all
    select t.Name, t.type from sys.objects t
    ) dt
where dt.type = 'U'
Run Code Online (Sandbox Code Playgroud)

执行计划是: 在此输入图像描述 在此输入图像描述

两者都相同,50%

Nic*_* N. 5

SQL Server查询优化器,让您得到几乎相同的性能优化了查询.


Dmi*_*sev 0

在我的实践中,第一个选项永远不会比第二个选项慢。我认为优化器足够聪明,可以或多或少以相同的方式优化这些计划。不过我做了一些测试,第一个选项总是更好。例如:

CREATE TABLE #a ( a INT, b INT );

WITH Numbers ( I ) AS (
    SELECT 1000

    UNION ALL

    SELECT I + 1
    FROM Numbers
    WHERE I < 5000
)
INSERT INTO #a ( a )
SELECT I
FROM Numbers
ORDER BY CRYPT_GEN_RANDOM(4)
OPTION ( MAXRECURSION 0 );

WITH Numbers ( I ) AS (
    SELECT 1000

    UNION ALL

    SELECT I + 1
    FROM Numbers
    WHERE I < 5000
)
INSERT INTO #a ( b )
SELECT I
FROM Numbers
ORDER BY CRYPT_GEN_RANDOM(4)
OPTION ( MAXRECURSION 0 );

SELECT a, b
FROM #a
WHERE a IS NOT NULL
UNION ALL
SELECT a, b
FROM #a
WHERE b IS NOT NULL

SELECT *
FROM (
    SELECT a, b
    FROM #a
    UNION ALL
    SELECT a, b
    FROM #a
    ) c
WHERE a IS NOT NULL
    OR b IS NOT NULL
Run Code Online (Sandbox Code Playgroud)

结果是 47% vs 53%