【问题标题】:What are the advantages/disadvantages of using a CTE?使用 CTE 的优点/缺点是什么?
【发布时间】:2010-09-08 10:11:45
【问题描述】:

我正在考虑提高某些 SQL 的性能,目前 CTE 正在脚本中被多次使用和引用。我会改用表变量来改进吗? (不能使用临时表,因为代码在函数中)。

【问题讨论】:

  • 查看Craig Freedman对SQL Server的详细解释link text

标签: sql sql-server common-table-expression


【解决方案1】:

可能不会。 CTE 尤其擅长查询树结构的数据。

【讨论】:

    【解决方案2】:

    您真的必须进行性能测试 - 没有是/否的答案。根据 Andy Living 的上述链接,CTE 只是查询或子查询的简写。

    如果您在同一个函数中调用它两次或更多次,则填充表变量然后加入/从中选择可能会获得更好的性能。但是,由于表变量在某处占用空间,并且没有索引/统计信息(表变量上声明的任何主键除外),因此无法说哪个会更快。

    他们都有成本和节省,哪种方法最好取决于他们提取的数据以及他们如何处理这些数据。我遇到过你的情况,在测试了各种条件下的速度之后 - 一些函数使用 CTE,而其他函数使用表变量。

    【讨论】:

      【解决方案3】:

      CTE 的优势

      CTE 可以称为“临时视图”,在某些情况下用作视图的良好替代品。 视图的主要优点是内存的使用。由于 CTE 的范围仅限于其批次,因此一旦超过其批次,分配给它的内存就会被刷新。但是一旦创建了一个视图,它就会被存储,直到用户删除它。如果视图在创建后没有被使用,那么它只是浪费内存。 与 View 相比,CTE 执行的 CPU 成本更低。 与 View 一样,CTE 不存储其定义的任何元数据并提供更好的可读性。 一个 CTE 可以在一个查询中被引用多次。 由于范围仅限于批处理,因此多个 CTE 可以具有视图不能具有的相同名称。 它可以是递归的。

      CTE 的缺点

      虽然使用 CTE 是有利的,但需要牢记一些限制, 我们知道它是视图的替代品,但 CTE 不能嵌套,而视图可以嵌套。 声明后的视图可以多次使用,但不能使用 CTE。每次你想使用它时都应该声明它。对于这种情况,不建议使用 CTE,因为用户一次又一次地声明批次是一项累人的工作。 在锚成员之间应该有 UNION、UNION ALL 或 EXCEPT 等运算符。 在递归 CTE 中,您可以定义许多锚成员和递归成员,但所有锚成员必须在第一个递归成员之前定义。您不能在两个递归成员之间定义锚成员。 Anchor 和 Recursive Members 中使用的列数、数据类型应该相同。 在递归成员中,不允许使用 TOP 等聚合函数、DISTINCT 等运算符、HAVING 和 GROUP BY 等子句、子查询、Left Outer 或 Right Outer 或 Full Outer 等连接。关于 Join,Recursive Member 中只允许 Inner Join。 Recursion Limit 为 32767,越过导致无限循环导致服务器崩溃。

      【讨论】:

        最近更新 更多