SQL 2005 CTE与TEMP表在其他表的连接中使用时的性能

Gra*_*tzy 12 sql t-sql sql-server sql-server-2005 common-table-expression

我有一个复杂的查询,我需要在后续查询(实际更新语句)中使用.我尝试过使用CTE和临时表.使用CTE的性能与临时表方法相比非常糟糕.它像15秒对毫秒.为了简化测试而不是在后续查询中加入CTE/Temp表,我只是从中选择了*.在那种情况下,他们执行相同的操作

我已经查看了两种方法的执行计划,这两种方法都使用了后续查询中的连接,然后只需选择*.与简单选择查询计划大致相同,但在后续选择连接时查询计划不是.具体来说,用于创建和填充临时表的查询计划部分保持不变,而用于创建和填充CTE的查询计划部分随后在具有连接的查询中使用时会发生显着变化.

我的问题是为什么CTE的创建和填充的查询计划根据临时表的后续使用方式而改变.同样在什么情况下,CTE会比临时表产生更好的性能?

*注意我也使用了表变量,它与临时表方法相当.

谢谢

Qua*_*noi 13

CTE 只是查询的别名.

它可能(或可能不)每次使用时重新运行.

没有干净的方法强制CTE实现SQL Server(比如Oracle /*+ MATERIALIZE */),你必须做这样的肮脏技巧:

CTE如果用于仅需要一次评估的计划(如HASH JOIN,MERGE JOIN等),则可以提高性能.

在这些场景中,哈希表将直接构建CTE,而使用临时表将需要评估CTE,将结果拉入临时表并再次读取临时表.


Stu*_*rth 9

你问的是一个复杂的问题,所以你得到一个复杂的答案:这取决于你.(我讨厌那个回应).

但是,严重的是,它与优化程序如何选择数据计划(您已经知道)有关; 临时表或变量类似于永久结构,因为执行计划将首先执行与填充该结构相关联的操作,然后在后续操作中使用该结构.CTE不是临时表; CTE的使用在后续操作使用之前不会计算,因此使用会影响计划的优化方式.

CTE是针对可重用性和维护问题而实施的,不一定是性能; 然而,在许多情况下(如递归),它们将比传统的编码方法表现更好.