Quais regras determinam quando o SQL Server usa um CTE como uma "cerca de otimização"?

10

Há algum tempo, Brent Ozar publicou uma postagem detalhando algumas das diferenças entre o SQL Server e o PostgreSQL:

Duas diferenças importantes entre o SQL Server e o PostgreSQL

O primeiro ponto (“CTEs são cercas de otimização”) chamou minha atenção, porque é óbvio que, no exemplo fornecido, o SQL Server combina o CTE e a consulta principal e o otimiza como uma consulta única (em oposição ao comportamento oposto em PostgreSQL).

No entanto, esse comportamento parece contrário aos exemplos que eu já vi em outros blogs e classes de treinamento, onde o SQL Server trata o CTE como uma cerca de otimização, o que permite um melhor uso de índices, melhor desempenho etc. Por exemplo:

Uma maneira melhor de selecionar estrelas

Portanto, parece que o SQL Server "honra" o CTE como uma cerca de otimização às vezes. Existem bons recursos disponíveis que documentam a lista específica de casos conhecidos em que o SQL Server honrará o CTE de maneira confiável como uma cerca de otimização (ou o comportamento oposto)?

Bryan Rebok
fonte

Respostas:

10

... lista de casos conhecidos em que o SQL Server honrará com segurança o CTE como uma cerca de otimização

Qualquer lista desse tipo dependeria do comportamento observado, sem garantia de confiabilidade.

O otimizador de consultas do SQL Server nunca trata uma expressão de tabela comum como uma cerca de otimização em si , embora algumas construções sejam claramente difíceis de otimizar. CTEs recursivas são um bom exemplo disso.

Os CTEs são tratados de maneira muito semelhante às exibições / funções embutidas / subconsultas / tabelas derivadas e incorporados à consulta. Qualquer comportamento de "barreira" observado depende do otimizador não conseguir, ou decidir não otimizar através dessa borda permeável em princípio.

De um modo geral, quanto mais simples e mais "relacional" for o CTE, maior a probabilidade de o otimizador ser capaz de mover bits.

Os recursos que permitiriam ao otimizador considerar ou forçá-lo a materializar o 'resultado' de uma CTE foram sugeridos, mas ainda não foram implementados:

Enquanto isso, a solução mais comum é materializar explicitamente o conjunto de resultados intermediários em uma tabela ou variável de tabela temporária. Obviamente, isso requer um cenário não limitado a uma única declaração.

Paul White 9
fonte