3

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

4

3 回答 3

7

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

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

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

于 2008-09-15T20:17:54.313 回答
3

可能不是。CTE 特别擅长查询树结构的数据。

于 2008-09-10T14:30:02.070 回答
0

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,越过导致无限循环导致服务器崩溃。

于 2020-06-19T08:22:57.270 回答