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
显然,正如您自己所展示的那样,它可以。
为什么?最明显的原因是优化器知道临时表的大小。这为优化查询提供了更多信息。CTE 只是一个估计值。因此,您看到的改进是由于查询计划所致。
另一个原因是如果在查询中多次引用 CTE。SQL Server 不会具体化 CTE,因此定义代码将运行多次。
有时,您故意将 CTE 实现为临时表,以便可以向其中添加索引。这也可以提高性能。
话虽如此,我更喜欢避免使用临时表。优化器通常非常好。