CTE实现了计算吗?

时间:2019-03-06 01:27:34

标签: sql sql-server

我已经编写了一个UDF以在ETL清理过程中重复使用,并且正在尝试量化哪种方法更好。我想知道我的假设是否正确,即CTE将在调用时计算一个值并将其具体化,但担心它可能只是抽象了多次运行的计算。

要考虑的示例代码:

with cte as (select 'This is a test////////$$$$$$$$' as val),
    cteReplaceDollar as (select replace(val, '$', '') as val from cte),
    cteReplaceSlash as (select replace(val, '/', '') as val from cteReplaceDollar),
    cteReplaceEmpty as (select replace(val, ' ', '') as val from cteReplaceSlash)
select 
    * 
from 
    cteReplaceEmpty
where
    val = 'Thisisatest' and
    val > '' and
    isnumeric(val) = 0;

这是执行替换3次(乐观假设)还是18次(悲观假设)?基本上,它是实现类似于变量赋值的中间步骤,还是用作生成器表达式,其中对值的每个引用和集合中的每个值执行每个步骤?

1 个答案:

答案 0 :(得分:4)

通常,相对于Postgres,SQL Server不会实现CTE。

您可以通过检查查询的实际执行计划来确认。 我建议使用SentryOne Plan Explorer,它是一个很棒的工具。

https://www.sentryone.com/plan-explorer

在您的示例中,我希望看到7个对replace的呼叫。


好吧,我算错了。真正的答案是:

您应该检查实际的执行计划。

在您的示例中,它看起来像这样:

Filer

replace运算符中有9个对Filter的呼叫。

Compute scalar

Compute Scalar运算符中加上3个呼叫。

总共

12个。


因此,我们确认在此示例中SQL Server没有实现CTE。 (那是SQL Server 2017 Developer Edition)

一些进一步的阅读:

What's the difference between a CTE and a Temp Table?

Is there a performance difference between CTE , Sub-Query, Temporary Table or Table Variable?

Use of With Clause in SQL Server

Microsoft建议微软为CTE添加Materialize提示,类似于Oracle提供的服务:T-SQL Common Table Expression "Materialize" Option