链接 CTE 与临时表的性能影响

dev*_*per 4 sql t-sql sql-server common-table-expression sqlperformance

我有以下链式 CTE 查询(简化):

;WITH CTE1
AS(    
    SELECT * FROM TableA
),
CTE2
AS(
    SELECT * FROM TableB b INNER JOIN CTE1 c ON b.id = c.id
)

SELECT * FROM CTE2
Run Code Online (Sandbox Code Playgroud)

如果我打破 CTE 链并将 CTE1 的数据存储到临时表中,则整体查询的性能会提高(从 1 分 20 秒缩短到 8 秒)。

;WITH CTE1
AS(    
    SELECT * FROM TableA
)

SELECT * INTO #Temp FROM CTE1

;WITH CTE2
AS(
    SELECT * FROM TableB b INNER JOIN #Temp c ON b.id = c.id
)

SELECT * FROM CTE2
DROP TABLE #Temp
Run Code Online (Sandbox Code Playgroud)

CTE1和CTE2中有复杂的查询。我刚刚创建了一个简化版本来解释。

打破 CTE 椅子是否应该提高性能?

SQL Server版本:2008 R2

Gor*_*off 5

显然,正如您自己所展示的那样,它可以。

为什么?最明显的原因是优化器知道临时表的大小。这为优化查询提供了更多信息。CTE 只是一个估计值。因此,您看到的改进是由于查询计划所致。

另一个原因是如果在查询中多次引用 CTE。SQL Server 不会具体化 CTE,因此定义代码将运行多次。

有时,您故意将 CTE 实现为临时表,以便可以向其中添加索引。这也可以提高性能。

话虽如此,我更喜欢避免使用临时表。优化器通常非常好。

  • 真的。通常,SQL Server 对复杂查询和时态表计算出的估计值很差,查询的某些特定部分的结果会显着提高性能 (2认同)