Do msdn :
Ao contrário de uma tabela derivada, uma CTE pode ser auto-referenciada e pode ser referenciada várias vezes na mesma consulta.
Estou usando bastante CTEs, mas nunca pensei profundamente sobre os benefícios de usá-los.
Se eu fizer referência a um CTE várias vezes na mesma consulta:
- Existe algum benefício de desempenho?
- Se eu estiver fazendo uma autojunção, o SQL Server verificará as tabelas de destino duas vezes?
Como regra, um CTE NUNCA melhorará o desempenho .
Um CTE é essencialmente uma visão descartável. Não há estatísticas adicionais armazenadas, índices, etc. Funciona como um atalho para uma subconsulta.
Na minha opinião, eles podem ser facilmente usados em excesso (eu vejo muito uso excessivo de código no meu trabalho). Algumas boas respostas estão aqui, mas se você precisar se referir a algo mais de uma vez, ou for mais do que algumas centenas de milhares de linhas, coloque-o em uma
#temp
tabela e indexe-o.Um lugar além da recursão onde acho os CTEs incrivelmente úteis é ao criar consultas de relatórios complexos. Eu uso uma série de CTEs para obter partes dos dados de que preciso e, em seguida, combino na seleção final. Acho que eles são mais fáceis de manter do que fazer a mesma coisa com muitas tabelas derivadas ou 20 junções e acho que posso ter mais certeza de que ele retorna os dados corretos sem efeito de vários registros devido aos relacionamentos um-muitos em todas as diferentes junções. Deixe-me dar um exemplo rápido:
Então, separando os diferentes pedaços de informação que você deseja, você pode verificar cada parte individualmente (usando os selects comentados, descomentando cada um individualmente e executando apenas até aquele select) e se você precisar fazer uma alteração na despesa cálculo (neste exemplo), é mais fácil de encontrar do que quando todos estão misturados em uma consulta massiva. É claro que as consultas de relatórios reais para as quais uso isso geralmente são muito mais complicadas do que o exemplo.
Como sempre depende, mas há casos em que o desempenho é muito melhorado. Eu vejo isso com instruções INSERT INTO SELECT onde você usa um CTE para selecionar e depois usa isso no INSERT INTO. Pode ter a ver com o RCSI sendo definido para o banco de dados, mas para aqueles momentos em que muito pouco é selecionado, pode ajudar bastante.