Existe-t-il un moyen de rendre le résultat avec exactement 3 guides distincts et pas plus? J'espère être en mesure de mieux répondre aux questions à l'avenir en incluant des guides de plan avec des requêtes de type CTE qui sont référencées plusieurs fois pour surmonter certaines bizarreries de SQL Server CTE.
Pas aujourd'hui. Les expressions de table communes non récursives (CTE) sont traitées comme des définitions de vue en ligne et développées dans l'arborescence de requête logique à chaque endroit où elles sont référencées (tout comme les définitions de vue normales) avant l'optimisation. L'arbre logique de votre requête est:
LogOp_OrderByCOL: Union1007 ASC COL: Union1015 ASC
LogOp_Project COL: Union1006 COL: Union1007 COL: Union1014 COL: Union1015
LogOp_Join
LogOp_ViewAnchor
LogOp_UnionAll
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_ViewAnchor
LogOp_UnionAll
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
Remarquez les deux ancres de vue et les six appels à la fonction intrinsèque newid
avant que l'optimisation ne démarre. Néanmoins, de nombreuses personnes considèrent que l'optimiseur devrait être capable d'identifier que les sous-arborescences développées étaient à l'origine un seul objet référencé et de simplifier en conséquence. Il y a également eu plusieurs demandes Connect pour permettre la matérialisation explicite d'un CTE ou d'une table dérivée.
Une implémentation plus générale aurait pour optimiseur d'envisager de matérialiser des expressions communes arbitraires pour améliorer les performances ( CASE
avec une sous-requête est un autre exemple où des problèmes peuvent survenir aujourd'hui). Microsoft Research a publié un document (PDF) à ce sujet en 2007, bien qu'il reste à ce jour non implémenté. Pour le moment, nous sommes limités à une matérialisation explicite utilisant des choses comme les variables de table et les tables temporaires.
SQLKiwi a mentionné l'élaboration de plans dans SSIS, existe-t-il un moyen ou un outil utile pour aider à établir un bon plan pour SQL Server?
C'était juste un vœu pieux de ma part et cela allait bien au-delà de l'idée de modifier les guides de plan. Il est possible, en principe, d'écrire un outil pour manipuler directement le XML de show plan, mais sans une instrumentation d'optimiseur spécifique, l'utilisation de l'outil serait probablement une expérience frustrante pour l'utilisateur (et le développeur y penserait).
Dans le contexte particulier de cette question, un tel outil serait toujours incapable de matérialiser le contenu CTE d'une manière qui pourrait être utilisée par plusieurs consommateurs (pour alimenter les deux entrées à la jointure croisée dans ce cas). L'optimiseur et le moteur d'exécution prennent en charge les bobines multi-consommateurs, mais uniquement à des fins spécifiques - dont aucune ne pourrait être appliquée à cet exemple particulier.
Bien que je ne sois pas certain, j'ai une intuition assez forte que les RelOps peuvent être suivies (boucle imbriquée, bobine différée) même si la requête n'est pas exactement la même que le plan - par exemple si vous avez ajouté 4 et 5 au CTE , il continue à utiliser le même plan (apparemment - testé sur SQL Server 2012 RTM Express).
Il y a ici une flexibilité raisonnable. La forme générale du plan XML est utilisée pour guider la recherche d'un plan final (bien que de nombreux attributs soient complètement ignorés, par exemple le type de partitionnement sur les échanges) et les règles de recherche normales sont également considérablement assouplies. Par exemple, l'élagage précoce des alternatives basées sur des considérations de coût est désactivé, l'introduction explicite de jointures croisées est autorisée et les opérations scalaires sont ignorées.
Il y a trop de détails pour être approfondi, mais le placement des filtres et des scalaires de calcul ne peut pas être forcé, et les prédicats du formulaire column = value
sont généralisés de sorte qu'un plan contenant X = 1
ou X = @X
peut être appliqué à une requête contenant X = 502
ou X = @Y
. Cette flexibilité particulière peut grandement aider à trouver un plan naturel à forcer.
Dans l'exemple spécifique, l'union constante peut toujours être implémentée en tant que balayage constant; le nombre d'entrées dans l'Union Tout n'a pas d'importance.