简体   繁体   English

CTE是否会改善性能?

[英]Do CTEs improve performance?

with ini as
(
    select ... 
)
select ini.a 
join ini.b 
join ini.c

How many times does the SQL Server engine calculate the results from the ini table ? SQL Server引擎从inicalculate结果多少次?

My question which I'm trying to answer (with your help) is if the with statement (CTE) improves performance by aliasing the results. 我想(在您的帮助下)回答的问题是with语句(CTE)是否通过aliasing化结果来提高性能。

The CTE ini is simply a macro that expands and this use is syntax/clarity only. CTE ini只是一个扩展的宏,此用法仅是语法/声明。 MSDN says: MSDN说:

Using a CTE offers the advantages of improved readability and ease in maintenance of complex queries 使用CTE的优点是提高了可读性,并易于维护复杂的查询

Nothing about performance. 与性能无关。

It is evaluated per mention : so three times here which you can see from an execution plan. 每次提及都会对其进行评估:因此在这里您可以从执行计划中看到3次。

For recursive CTEs it's somewhat different as the CTE builds upon itself but it will still be evaluated once per mention 对于递归CTE,它在CTE自身基础上有所不同,但每次提及仍会进行评估

A CTE (common table expression, the part that is wrapped in the "with") is essentially a 1-time view. CTE(公用表表达式,包装在“ with”中的部分)本质上是1次视图。 If you think of it in terms of a temporary view, perhaps the answer will become more clear. 如果从临时的角度来看,答案可能会更加清晰。 As far as I know, the interpreter will simply do the equivalent of copy/pasting whatever is within the CTE into the main query wherever it finds the reference. 据我所知,解释器将在找到引用的任何地方简单地将CTE中的内容复制/粘贴到主查询中。

I'm sure there are outside instances where it appears to help, but more often than not, I'd assume that the mere presence of a CTE itself is not going to improve the performance of a query. 我确信在外部实例中它似乎可以提供帮助,但通常,我认为仅存在CTE本身并不会提高查询性能。 It'll help with readability and re-usability within that single select statement (ie, you won't have to re-type the same sub-query multiple times), but I don't believe it will magically make things run faster (all things being equal). 这将有助于在单个select语句中实现可读性和可重用性(即,您不必多次键入相同的子查询),但是我认为这样做不会神奇地使事情运行得更快(所有的事情都是平等)。 Of course, if your query is structured differently within the CTE than you would have done w/ sub-queries, then it's quite possible the CTE runs faster at that point, but you're now comparing apples to oranges. 当然,如果您的查询在CTE中的结构与执行子查询时的结构不同,那么CTE很有可能在那时运行得更快,但是现在您正在比较苹果和橘子。

I suppose it would also depend on whther you were using it to replace a derived table or a correlated subquery. 我想它还取决于您使用它来替换派生表或相关子查询的方式。 Performance would be about the same in the first case and probably significantly better in the second if you joined to the CTE rather than just replaced the suquery code with a reference to the CTE. 如果您加入CTE,而不是仅仅使用对CTE的引用替换suquery代码,则在第一种情况下性能将大致相同,而在第二种情况下可能会显着提高。 If you used it to replace a where NOT EXISTS clause with a left join to a CTE (in order to find the records in one table but not the other), I'd expect performance to be worse as Where Exists is usually the fastets way to do that type of task. 如果您使用它用CTE的左连接替换where NOT EXISTS子句(以便在一个表中找到记录,但不在另一个表中),那么我希望性能会更差,因为Where Exists通常是固定方式做这种类型的任务。 I guess what I'm saying is that performance will still depend on how you use the CTE not just the fact that you generated one. 我想我想说的是,性能仍然取决于您使用CTE的方式,而不仅仅是生成CTE的事实。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM