子查询可以生成与 CTE 不同的执行计划吗?

Jam*_*mes 3 sql-server-2008 sql-server cte subquery

我正在与老板交谈,他更喜欢子查询而不是 CTE。就个人而言,我讨厌子查询。他提到子查询可以更快,但我不相信。我运行了这个简短的测试:

    with classes as 
    (select top 10 Classkey from dimclass
    group by classkey
    order by count(1) desc),
    policies as (
    select CarrierKey, policykey, periodeffectivedate from dimpolicy),
    exposure as (
    select policykey, classkey  from DimExposure)


    select * from policies p
    inner join exposure x on p.PolicyKey = x.PolicyKey
    inner join classes c on x.ClassKey = c.Classkey
Run Code Online (Sandbox Code Playgroud)

有一个执行计划:

https://www.brentozar.com/pastetheplan/?id=SJYJUZNHS

    select p.CarrierKey, p.PolicyKey, p.periodeffectivedate from dimpolicy p
    inner join (select policykey, classkey  from DimExposure) x on p.PolicyKey = x.PolicyKey
    inner join (select top 10 Classkey from dimclass
                group by classkey
                order by count(1) desc) c on x.ClassKey = c.Classkey
Run Code Online (Sandbox Code Playgroud)

有相同的执行计划:

https://www.brentozar.com/pastetheplan/?id=rJs_LbVSr

问题:总是这样吗?在 SQL Server 奇异而奇妙的世界中,答案似乎总是取决于.

Joe*_*ish 6

按原样,我认为这个问题无法回答。不可能证明是否定的,并且您不会在产品文档中找到保证。如果您想了解两种方法之间的技术差异示例,请观看 Paul White 的Query Optimizer Deep Dive会话的几分钟。目前尚不清楚有人如何将其转化为性能最佳实践。

我建议将这个问题作为编码风格的问题来解决,而不是试图找到性能最佳实践。为派生表切换 CTE 或为 CTE 切换派生表不是重写查询的有意义的方式。