CTE ou non CTE
-
26-09-2019 - |
Question
Après avoir été coincé avec SQL2000 pour beaucoup trop longtemps, je ne l'ai pas vraiment eu beaucoup d'exposition à des expressions de table communes.
Les réponses que j'ai donné ici (# 4025380) et ici (# 4018793) sont allés contre le courant en ce sens qu'ils n'utilisent pas un CTE.
Je comprends que pour récursion ils sont Beez Kneez, et il y a quelques requêtes qui peuvent être grandement simplifiées par leur utilisation, mais à quel point est leur utilisation tout simplement frivole? Est-ce qu'ils ont un grand avantage de performance sur une sous-requête ou une jointure? Ont-ils vraiment le code Simplifier et rendre plus maintenable?
En bref, quand est-il une bonne pratique d'utiliser un CTE sur une syntaxe « moindre ».
La solution
Vous devriez généralement utiliser un CTE sur une sous-requête normale si:
- Votre requête nécessite récursion (comme vous l'avez dit)
- La sous-requête est grand ou complexe
- La requête contenant est grand ou complexe
- La sous-requête est répété (ou au moins plusieurs sous-requêtes peut être simplifiée en effectuant différentes opérations simples sur un sous-requête commune)
En bref, oui ils font des requêtes plus lisible lorsque bien utilisé.
Autres conseils
Personnellement, une fois que je suis à l'aise de les utiliser, je pense qu'ils produisent plus propre, le code plus lisible. À titre d'exemple, comparer votre réponse à la mienne sur # 4018793 . Nous avons fait essentiellement la même chose; J'ai utilisé un CTE et vous n'avez pas.
Votre réponse sans CTE:
SELECT
course,
section,
grade,
gradeCount
FROM
table
INNER JOIN
(SELECT
grade,
Max(gradeCount) as MaxGradeCount
FROM
table
) MaxGrades
ON table.grade = MaxGrades.grade
AND table.gradeCount = MaxGrades.MaxGradeCount
ORDER BY
table.grade
Ma réponse avec CTE:
;with cteMaxGradeCount as (
select
grade,
max(gradeCount) as MaxGradeCount
from @Test
group by grade
)
select
t.course,
t.SECTION,
t.grade,
t.gradeCount
from cteMaxGradeCount c
inner join @Test t
on c.grade = t.grade
and c.MaxGradeCount = t.gradeCount
order by t.grade
Ils sont le sucre syntaxique, à l'exception des requêtes hiérarchiques / récursives.
Cependant, tout ce qui peut être fait de manière récursive devrait être - la génération de date par CTE récursive était à peine mieux qu'un curseur -. Le tour de table NUMÉROS échelle beaucoup mieux
CTE donne un résultat plus rapide dans un scénario récurrent. Le résultat de CTE est utilisé à plusieurs reprises pour obtenir le dernier ResultSet. Donc, depuis que vous avez pris votre clause where ou sous-requête dans CTE, sans aucun doute, il va montrer une amélioration de la performance.
Référence: http://msdn.microsoft.com/ fr-fr / bibliothèque / ms190766 (v = SQL.105) .aspx
Juste une note, dans de nombreux scénarios, tables temporaires donne de meilleures performances puis CTE aussi, vous devriez donc donner un essai aux tables temporaires ainsi.
Référence: http: //social.msdn .microsoft.com / Forums / fr / TransactSQL / fil / d040d19d-016e-4a21-bf44-a0359fb3c7fb