我有下面的SQL CTE声明,我发现它是性能的瓶颈。在调试时,它只是挂起(我认为它会进行表扫描)所以我用临时表替换它,查询运行正常。我想知道CTE表达式的编写方式是否有所不同,这使得语句挂起。我知道CTE附带了一些性能影响,但我不认为我在下面的查询中做了什么特别的事情让CTE给我这么糟糕的表现。
;with ContList (ContKey, CKey, CreatedDate, DeletedDate, SourceId) AS
(
SELECT ContKey, CKey, CreatedDate, DeletedDate, SourceId FROM #someTempTable
UNION ALL
SELECT list.ContKey AS ContKey,
fact.CKey AS CKey,
case when fact.CreatedDate > list.CreatedDate then fact.CreatedDate else list.CreatedDate end AS CreatedDate,
case when isnull(fact.DeletedDate, '9999/01/01') < isnull(list.DeletedDate, '9999/01/01') then fact.DeletedDate else list.DeletedDate end AS DeletedDate,
fact.DataSourceDimKey As SourceId
FROM ContList list
INNER JOIN SomeFact fact ON list.CKey = fact.DimKey
INNER JOIN SomeDimvw someDim on someDim.SomeKey = fact.SomeKey
INNER JOIN #contTypes contTypes on someDim.SomeTypeId = contTypes.SomeTypeId
WHERE list.DeletedDate IS NULL
)
我用以下代码替换了上面的查询:
SELECT ContKey, CKey, CreatedDate, DeletedDate, SourceId FROM #someTempTable
UNION ALL
SELECT list.ContKey AS ContKey,
fact.CKey AS CKey,
case when fact.CreatedDate > list.CreatedDate then fact.CreatedDate else list.CreatedDate end AS CreatedDate,
case when isnull(fact.DeletedDate, '9999/01/01') < isnull(list.DeletedDate, '9999/01/01') then fact.DeletedDate else list.DeletedDate end AS DeletedDate,
fact.DataSourceDimKey As SourceId
into #ContList
FROM #ContList list
INNER JOIN SomeFact fact ON list.CKey = fact.DimKey
INNER JOIN SomeDimvw someDim on someDim.SomeKey = fact.SomeKey
INNER JOIN #contTypes contTypes on someDim.SomeTypeId = contTypes.SomeTypeId
WHERE list.DeletedDate IS NULL
)
答案 0 :(得分:3)
我最近有一个(可能是相关的)情况,使用CTE的复杂查询会产生不一致的结果,具体取决于提供的参数。
例如:
第一次测试:
第二次测试:
原来,为“A”生成的查询计划是有效的,而为“B”生成的查询计划则不是;由于查询计划是缓存的,因此第一个查询在重新启动服务器控制所有查询的性能后运行。
解决方案是强制重建数据库的统计信息。
答案 1 :(得分:1)
CTE只是语法。它被执行了。在循环连接中,CTE被执行多次。 #temp已实现,因此只运行一次。
答案 2 :(得分:0)
通过SQL Server MVP Gail Shaw检查此QnA和响应:
http://www.sqlservercentral.com/Forums/Topic415829-338-1.aspx
简而言之, CTE 就像临时视图,当您检查执行计划时,它会内联到查询中。 TempTables 是在tempDB中创建的表。
表比视图更快(在您的情况下是递归视图)。希望这能解释两种方法之间的性能差异。