为啥 CTE 比游标/派生表/子查询/临时表等更好?

Posted

技术标签:

【中文标题】为啥 CTE 比游标/派生表/子查询/临时表等更好?【英文标题】:Why is CTE better than cursor/derived table/ subqueries/ temp table etc.?为什么 CTE 比游标/派生表/子查询/临时表等更好? 【发布时间】:2011-07-26 02:44:01 【问题描述】:

与派生表/子查询/临时表等方法相比,CTE 如何以及为什么提供更好的性能?

任何临时计算都发生在临时数据库中。因此,如果我们有游标方法,它还会在临时数据库中创建临时表/工作表,一旦操作结束,该工作表就会被销毁。我对 CTE 的理解是,它也有同样的作用(或者它是否会在内存中创建临时结果?从而提高性能)那么为什么它比上述方法(如游标/派生表/子查询/临时表等)更好?

【问题讨论】:

具体例子?这是一个相当笼统的陈述,是不真实的。 总的来说,我正在寻找答案......没有什么特别的...... CTES 并没有什么神奇的地方可以让它们比具有子查询的等效查询更快或更慢。有些用例只能通过 CTES 有效地实现,例如递归,但它的极端情况非常严重。 主要原因是:游标是一个过程结构——你创建它,你一步一步地完成它。这对于通用编程来说很好——但它完全违背了 SQL Server 的基于集合的思想和工作方式。光标是内存和性能的猪(在大多数情况下),所以在何时何地使用它们时要非常小心。 90% 或更多的时间您真的不需要光标 - 您可以使用基于集合的方法做到这一点(或者更好!) @marc_s:当然,在幕后,基于集合的方法使用循环来处理结果集,但最大的区别是这些是 SQL Server 的内部快速循环(请不要让任何人接受意思是我提倡使用游标。不要!) 【参考方案1】:

A(非递归)CTE 不使用游标。它是一种基于集合的方法。与使用游标相比,这是最大的区别。但是一般情况下不使用游标也是如此。

应尽可能避免使用光标(我相信我们都知道)。

CTE 不一定比使用派生表更好,但确实会导致 TSQL 代码更易于理解。 CTE 实际上只是查询或子查询的简写。类似于临时视图的东西。

CTE 可能不是最佳方法的情况是,查询计划优化器对 CTE 的行估计不准确。

相关问题:What are the advantages/disadvantages of using a CTE?

【讨论】:

+1 游标是魔鬼的工作 - 尽可能远离它们!特别是在触发器中......(我现在有一个如此糟糕的数据库要处理......) 是的,在触发器内部 - 在该游标内部,另一个表被更新并触发另一个触发器......内部有另一个游标......这个数据库真的应该被复制到 DEV:NULL永远…… 如果 ACM 或任何人需要一个真正可怕的数据库的例子来做所有被禁止和不受欢迎的事情 - 这里有一个很好的例子:-) 然后人们问“为什么慢?” :p。我从游标方法到彼此重叠的 8 层 CTE(最后的 UPDATE 语句是第 9 层)并将 6 小时的批处理改进为 4 分钟!!! @barrypicker,可读性很好(它总是很复杂)。这些层是最必要的,因此您可以将值 x 定义为 column1 * column2(实际上是一个时髦的案例陈述),然后,在 layer2 中,您可以在另一个计算中使用 x 而不会加倍(并打破 DRY 原则)。跨度>

以上是关于为啥 CTE 比游标/派生表/子查询/临时表等更好?的主要内容,如果未能解决你的问题,请参考以下文章

sql 视图,临时表,CTE,派生表

SQL Server临时表表标量和CTE

sql 表表达式 - 视图,临时表,表变量,派生表,表值函数,公用表表达式(CTE)

在某些情况下,为什么CTE(公用表表达式)与SQL Server中的临时表相比会减慢查询速度

何时使用公用表表达式 (CTE)

SQL Server 公用表表达式(CTE)实现递归