Quelles règles déterminent lorsque SQL Server utilise un CTE comme «clôture d'optimisation»?

10

Il y a quelque temps, Brent Ozar a publié un article détaillant certaines des différences entre SQL Server et PostgreSQL:

Deux différences importantes entre SQL Server et PostgreSQL

Le premier point («les CTE sont des clôtures d'optimisation») a attiré mon attention, car il est évident que dans l'exemple fourni, SQL Server combine le CTE et la requête principale ensemble et l'optimise en une seule requête (par opposition au comportement opposé dans PostgreSQL).

Cependant, ce comportement semble contraire aux exemples que j'ai vus dans d'autres blogs et cours de formation, où SQL Server traite le CTE comme une clôture d'optimisation, ce qui permet une meilleure utilisation des index, de meilleures performances, etc. Par exemple:

Une meilleure façon de sélectionner une étoile

Il semble donc que SQL Server «honore» le CTE comme une barrière d'optimisation PARFOIS. Existe-t-il de bonnes ressources disponibles qui documentent la liste spécifique des cas connus où SQL Server honorera de manière fiable le CTE en tant que barrière d'optimisation (ou le comportement opposé)?

Bryan Rebok
la source

Réponses:

10

... liste des cas connus où SQL Server honorera de manière fiable le CTE comme barrière d'optimisation

Une telle liste reposerait sur le comportement observé, sans aucune garantie de fiabilité.

L'optimiseur de requêtes SQL Server ne traite jamais une expression de table commune comme une clôture d'optimisation en soi , bien que certaines constructions soient clairement difficiles à optimiser. Les CTE récursifs en sont un bon exemple.

Les CTE sont traités de manière très similaire aux vues / fonctions en ligne / sous-requêtes / tables dérivées et intégrés dans la requête. Tout comportement de «barrière» observé dépend du fait que l'optimiseur n'est pas en mesure ou décide de ne pas optimiser à travers cette frontière perméable en principe.

De manière générale, plus le CTE est simple et plus «relationnel», plus il est probable que l'optimiseur sera capable de déplacer des bits.

Des fonctionnalités qui permettraient à l'optimiseur de prendre en compte ou l'obligeraient à matérialiser le «résultat» d'un CTE ont été suggérées, mais pas encore implémentées:

En attendant, la solution la plus courante consiste à matérialiser explicitement l'ensemble de résultats intermédiaire dans une table temporaire ou une variable de table. Cela nécessite évidemment un scénario non limité à une seule déclaration.

Paul White 9
la source