FROM子句中的子选择是否应优化为SQL Server中的派生表?

mat*_*ndr 3 sql-server

查询1:

SELECT au_lname, au_fname, title 
FROM (SELECT au_lname, au_fname, id FROM pubs.dbo.authors WHERE state = 'CA') as a 
JOIN pubs.dbo.titleauthor ta on a.au_id=ta.au_id 
JOIN pubs.dbo.titles t on ta.title_id = t.title_id
Run Code Online (Sandbox Code Playgroud)

查询2:

DECLARE @DATASET TABLE ( au_lname VARCHAR(10), au_fname VARCHAR(10), id INT );

INSERT @DATASET SELECT au_lname, au_fname, id FROM pubs.dbo.authors WHERE state = 'CA';

SELECT au_lname, au_fname, title 
FROM @DATASET DATASET as a 
JOIN pubs.dbo.titleauthor ta on a.au_id=ta.au_id 
JOIN pubs.dbo.titles t on ta.title_id = t.title_id
Run Code Online (Sandbox Code Playgroud)

我的假设是,从性能的角度来看,这两个查询彼此之间没有太大差异.查询2是否比查询1有所改进?

作为旁注,我知道这个例子中的子查询甚至不需要在那里.这是一个简化版本 - 我正在处理的实际查询要复杂得多.

JNK*_*JNK 5

如果您有多行数据,查询2很可能比查询1 更糟糕.

  • 您正在SELECT将数据输入两次 - 一次进入表变量并再次返回它
  • 表变量通常表现不佳 - 它们没有统计数据或索引,与普遍看法相反仍然写入tempdb和日志

如果是我,我会在没有派生表的情况下重写第一个查询,这实际上是不必要的:

SELECT 
    au_lname
    ,au_fname
    ,title 
FROM 
    pubs.dbo.authors a 
INNER JOIN 
    pubs.dbo.titleauthor ta 
        on a.au_id=ta.au_id 
INNER JOIN 
    pubs.dbo.titles t 
        on  ta.title_id = t.title_id
WHERE 
    a.state = 'CA'
Run Code Online (Sandbox Code Playgroud)

注意 有关表变量和临时表的更多信息,请参阅Martin Smith的这个史诗回答.