J'ai écrit un fichier UDF à valeur table qui commence par un CTE pour renvoyer un sous-ensemble des lignes d'une grande table. Il existe plusieurs jointures dans le CTE. Un couple d'internes et un à gauche se joignent à d'autres tables, qui ne contiennent pas beaucoup de lignes. Le CTE comporte une clause where qui renvoie les lignes dans une plage de dates, afin de renvoyer uniquement les lignes nécessaires.CTE SQL Server référencé dans les jointures lentes
Je référence alors ce CTE dans 4 jointures à gauche, afin de construire des sous-totaux en utilisant différents critères.
La requête est assez complexe, mais voici une pseudo-version simplifiée de celui-ci
WITH DataCTE as
(
SELECT [columns] FROM table
INNER JOIN table2
ON [...]
INNER JOIN table3
ON [...]
LEFT JOIN table3
ON [...]
)
SELECT [aggregates_columns of each subset] FROM DataCTE Main
LEFT JOIN DataCTE BananasSubset
ON [...]
AND Product = 'Bananas'
AND Quality = 100
LEFT JOIN DataCTE DamagedBananasSubset
ON [...]
AND Product = 'Bananas'
AND Quality < 20
LEFT JOIN DataCTE MangosSubset
ON [...]
GROUP BY [
J'ai le sentiment que SQL Server devient confus et appelle le CTE pour chaque jointure réflexive, ce qui semble confirmé en regardant le plan d'exécution, bien que j'avoue ne pas être un expert en les lisant.
J'aurais supposé que SQL Server était suffisamment intelligent pour effectuer une seule fois la récupération de données à partir du CTE, plutôt que de le faire plusieurs fois. J'ai essayé la même approche mais plutôt que d'utiliser un CTE pour obtenir le sous-ensemble des données, j'ai utilisé la même requête de sélection que dans le CTE, mais je l'ai fait sortir dans une table temporaire à la place.
La version référençant la version CTE prend 40 secondes. La version référençant la table temporaire prend entre 1 et 2 secondes.
Pourquoi SQL Server n'est-il pas assez intelligent pour conserver les résultats du CTE en mémoire? J'aime les CTE, particulièrement dans ce cas, car mon UDF est une table, donc cela m'a permis de tout garder dans une seule déclaration.
Pour utiliser une table temporaire, j'aurais besoin d'écrire une table UDF à plusieurs tables, ce que je trouve une solution légèrement moins élégante. Est-ce que certains d'entre vous ont eu ce genre de problèmes de performance avec CTE, et si oui, comment les avez-vous triés?
Merci,
Kharlos
Pouvez-vous publier votre plan d'exécution? –