什么规则确定何时SQL Server使用CTE作为“优化围栏”?


10

不久前,Brent Ozar发表了一篇文章,详细介绍了SQL Server和PostgreSQL之间的一些区别:

SQL Server与PostgreSQL之间的两个重要区别

第一点(“ CTE是优化栅栏”)引起了我的注意,因为很明显,在所提供的示例中,SQL Server将CTE和主查询组合在一起,并将其优化为单个查询(与之相反的行为是, PostgreSQL)。

但是,此行为似乎与我在其他博客和培训课程中看到的示例相反,在这些示例中,SQL Server确实将CTE视为优化围栏,从而可以更好地使用索引,提高性能等。例如:

选择星号的更好方法

因此,似乎SQL Server有时会“荣誉” CTE作为优化的围栏。是否有可用的良好资源来记录已知情况的特定列表,在这些情况下,SQL Server将可靠地认可CTE作为优化范围(或相反的行为)?

Answers:


10

...在已知情况下,SQL Server将可靠地认可CTE作为优化围栏的列表

任何此类列表都将依赖于观察到的行为,而不能保证可靠性。

SQL Server查询优化器从不将公用表表达式本身视为优化围栏,尽管显然很难对某些构造进行优化。递归CTE是一个很好的例子。

CTE与视图/内联函数/子查询/派生表非常相似,并内联到查询中。任何观察到的“围栏”行为都取决于优化程序无法或决定不跨该原理内可渗透边界进行优化。

一般而言,CTE越简单且越“相关”,则优化器越有可能能够移动位。

已经提出了一些功能,这些功能将允许优化器考虑或迫使其实现CTE的“结果”,但尚未实现:

同时,最常见的解决方法是在临时表或表变量中显式实现中间结果集。显然,这需要不限于单个语句的方案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.