web-dev-qa-db-fra.com

Différence entre CTE et SubQuery?

À partir de cet article Comment utiliser ROW_NUMBER dans la procédure suivante?

Il existe deux versions de réponses où l'une utilise SubQuery et l'autre utilise CTE pour résoudre le même problème.

Maintenant, quel est l’avantage d’utiliser une CTE (Common Table Expression) sur un sub-query (donc, plus lisible que fait réellement la requête)

Le seul avantage de l'utilisation d'une CTE sur une sous-sélection est que je peux réellement name la sous-requête. Existe-t-il d'autres différences entre ces deux lorsqu'un CTE est utilisé comme un simple CTE (non récursif??

134
Sung M. Kim

Dans la sous-requête vs simple (non récursive) versions CTE, elles sont probablement très similaires. Vous devrez utiliser le profileur et le plan d’exécution réel pour repérer les différences éventuelles, ce qui est propre à votre configuration (nous ne pouvons donc pas vous donner la réponse complète).

Dans général; Un CTE peut être utilisé de manière récursive; une sous-requête ne peut pas. Cela les rend particulièrement bien adaptés aux structures arborescentes.

90
Marc Gravell

Le principal avantage de Common Table Expression (lorsque vous ne l'utilisez pas pour requêtes récursives ) est l'encapsulation, au lieu de devoir déclarer la sous-requête à chaque emplacement que vous souhaitez utiliser. Si vous le définissez une fois, vous avez plusieurs références.

Cependant, cela ne signifie pas qu'il ne soit exécuté qu'une seule fois (comme itérations précédentes de cette même réponse , merci à tous ceux qui ont commenté). La requête a certainement le potentiel d’être exécutée plusieurs fois si elle est référencée plusieurs fois; l'optimiseur de requête prend finalement la décision quant à comment le CTE doit être interprété.

78
casperOne

Les CTE sont les plus utiles pour la récursivité:

WITH hier(cnt) AS (
        SELECT  1
        UNION ALL
        SELECT  cnt + 1
        FROM    hier
        WHERE   cnt < @n
        )
SELECT  cnt
FROM    hier

retournera @n rangées (jusqu'à 101). Utile pour les calendriers, les ensembles de lignes factices, etc.

Ils sont également plus lisibles (à mon avis).

En dehors de cela, CTE 'et subqueries sont identiques.

15
Quassnoi

Une différence qui n’a pas été mentionnée est qu’un seul CTE peut être référencé dans les différentes parties d’un syndicat.

10
user340140

À moins que quelque chose ne me manque, vous pouvez nommer les CTE et les sous-requêtes tout aussi facilement.

Je suppose que la principale différence est la lisibilité (je trouve que le CTE est plus lisible car il définit votre sous-requête au début plutôt qu'au milieu).

Et si vous devez faire quelque chose avec la récursion, vous aurez un peu de difficulté à le faire avec une sous-requête;)

8
AlexCuse

Un fait important que personne n’a mentionné est que (au moins dans postgres), les CTE sont des barrières d’optimisation:

https://blog.2ndquadrant.com/postgresql-ctes-are-optimization-fences/

Autrement dit, ils seront traités comme leur propre requête atomique, plutôt que intégrés dans le plan de requête complet. Il me manque l'expertise pour donner une meilleure explication, mais vous devriez vérifier la sémantique de la version de SQL que vous utilisez; pour les utilisateurs avancés, la création d'une clôture d'optimisation peut améliorer les performances si vous maîtrisez le planificateur de requêtes; Dans 99% des cas, cependant, vous devriez éviter d'essayer de dire au planificateur de requêtes quoi faire, car ce que vous pensez être plus rapide est probablement pire que ce qu'il pense qu'il sera plus rapide. :-)

7
Ajax

En ajoutant aux réponses des autres, si vous utilisez plusieurs fois la même sous-requête, vous pouvez remplacer toutes ces sous-requêtes par un seul CTE. Cela vous permet de mieux réutiliser votre code.

6
A-K

Une chose que vous devez également comprendre est que, dans les anciennes versions de SQL Server (oui, de nombreuses personnes doivent toujours prendre en charge les bases de données SQL Server 2000), les CTE ne sont pas autorisés et que la table dérivée constitue votre meilleure solution.

4
HLGEM

CONSEIL: (MAXRECURSION n)

vous pouvez limiter le nombre de niveaux de récursivité autorisés pour une instruction spécifique en utilisant l'indice MAXRECURSION et une valeur comprise entre et 2 767 dans l'élément OPTION clause

Par exemple, vous pouvez essayer:

OPTION 
      (MAXRECURSION 150)

GO
2
Basic_