J'ai rencontré ce problème récemment et je n'ai trouvé aucune discussion à ce sujet en ligne.
La requête ci-dessous
DECLARE @S VARCHAR(1) = '';
WITH T
AS (SELECT name + @S AS name2,
*
FROM master..spt_values)
SELECT *
FROM T T1
INNER JOIN T T2
ON T1.name2 = T2.name2;
Obtient toujours un plan de boucles imbriquées
Tenter de forcer le problème avec INNER HASH JOIN
ou des INNER MERGE JOIN
conseils produit l'erreur suivante.
Le processeur de requêtes n'a pas pu produire un plan de requête en raison des indications définies dans cette requête. Renvoyez la requête sans spécifier d'indices et sans utiliser SET FORCEPLAN.
J'ai trouvé une solution de contournement qui permet d'utiliser des jointures de hachage ou de fusion - en enveloppant la variable dans un agrégat. Le plan généré est nettement moins cher (19.2025 vs 0.261987)
DECLARE @S2 VARCHAR(1) = '';
WITH T
AS (SELECT name + (SELECT MAX(@S2)) AS name2,
*
FROM spt_values)
SELECT *
FROM T T1
INNER JOIN T T2
ON T1.name2 = T2.name2;
Quelle est la raison de ce comportement? et y a-t-il une meilleure solution de contournement que celle que j'ai trouvée? (cela ne nécessite peut-être pas les branches de plan d'exécution supplémentaires)