Y a-t-il une performance de différence sage entre ces 2 exemples:
WITH CTE1
AS (
SELECT
Col1,
Col2,
Col3
FROM dbo.Table1
WHERE Col3 = '1'
)
select * from CTE1
WITH CTE1
AS (
SELECT
Col1,
Col2,
Col3
FROM dbo.Table1
)
select * from CTE1
WHERE Col3 = '1'
Nous utilisons une CTE comme un sous-sélection dans une SQL dynamique et ne peut pas appliquer la clause WHERE jusqu'à ce que "Sélectionnez de CTE" se produise. Notre requête réelle est beaucoup plus compliquée que cela. Mais, je me demande si ce sera plus performant pour ne pas utiliser de CTE. Le deuxième exemple fera-t-il réellement tirer toutes les lignes de la table, puis appliquer le filtrage? Ou sont-ils fonctionnellement équivalents? Nous utilisons SQL Server.
Les deux requêtes ont le même plan d'exécution. Vous pouvez vérifier cela dans SQL Server Management Studio en tapant:
WITH CTE1 AS ( SELECT Col1, Col2, Col3 FROM dbo.Table1
WHERE Col3 = '1' )
SELECT * from CTE1
;WITH CTE2 AS ( SELECT Col1, Col2, Col3 FROM dbo.Table1
)
SELECT * from CTE2 WHERE Col3 = '1'
En ce qui concerne la deuxième partie de votre question: il est assez difficile de dire sans regarder le code actuel et comprendre ce que vous essayez de réaliser, mais vous pouvez constater que l'utilisation de la table temporaire peut être bien plus efficace que la CTE.
Je cours ces 2 questions contre Adventureworks2019, appelons-les:
" Query 1 "
WITH CTE1
AS (
SELECT
FirstName,
MiddleName,
LastName
FROM [Person].[Person]
WHERE LastName = 'Sánchez'
)
select * from CTE1
et " Query 2 "
WITH CTE1
AS (
SELECT
FirstName,
MiddleName,
LastName
FROM [Person].[Person]
)
select * from CTE1
WHERE LastName = 'Sánchez'
Ensuite, je suis allé au plan d'exécution, clic droit et Show Execution Plan XML...
Et je les ai comparé sur Notepad ++, ils sont pratiquement identiques:
La seule différence est la suivante:
MaxCompileMemory="2796560"
MaxCompileMemory="2796496"
Mais la divergence est trop petite pour dire qu'une requête est meilleure qu'une autre. Et aussi le calcul logique est exactement le même:
<RelOp AvgRowSize="126" EstimateCPU="0.00016745" EstimateIO="0.003125" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="9.5" EstimatedRowsRead="9.5" LogicalOp="Index Seek" NodeId="0" Parallel="false" PhysicalOp="Index Seek" EstimatedTotalSubtreeCost="0.00329245" TableCardinality="19972">
J'ai appuyé sur le bouton inclure les statistiques client et je l'ai fait 3 exécuté pour chaque requête:
Comme vous pouvez le voir ici, vous pouvez avoir plus de perspicacité, mais une fois encore, ils sont toutaux identiques.
J'espère que je vais vous apprendre à déboguer une requête via SSMS. Utilisez maintenant la même technique avec votre requête car votre base de données peut être différente, la table pourrait être plus grande et le résultat peut donc varier.
Mais dans l'ensemble, on peut dire que les deux requêtes sont les mêmes.