Eu estava conversando com o chefe, e ele prefere subconsultas sobre CTEs. Pessoalmente, eu detesto subconsultas. Ele mencionou que as subconsultas podem ser mais rápidas, mas não estou convencido. Fiz este pequeno teste:
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
tem um plano de excussão de:
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
tem o mesmo plano de execução:
https://www.brentozar.com/pastetheplan/?id=rJs_LbVSr
Pergunta: Isso é sempre assim? No mundo estranho e maravilhoso do SQL Server, a resposta sempre parece ser depende .
Como está, eu argumentaria que a pergunta não é passível de resposta. É impossível provar uma negativa e você não encontrará uma garantia na documentação do produto. Se você quiser um exemplo de uma diferença técnica entre as duas abordagens, assista a alguns minutos da sessão Deep Dive do Query Optimizer de Paul White. Não está claro como alguém poderia traduzir isso em uma melhor prática de desempenho.
Sugiro abordar o problema como uma questão de estilo de codificação, em vez de tentar encontrar uma prática recomendada de desempenho. Alternar um CTE para uma tabela derivada ou uma tabela derivada para um CTE não é uma maneira significativa de reescrever uma consulta.
Em geral, depende. Um caso em que um CTE é melhor do que uma tabela derivada é quando você precisa referenciá-lo várias vezes na consulta. Um exemplo bobo:
vs
Diferentes mecanismos de banco de dados tratam várias referências a um CTE de maneiras diferentes. No SQL Server, o CTE geralmente será totalmente avaliado para cada referência.