Esiste UN MODO per ottenere il risultato esattamente con 3 guide distinte e non di più? Spero di poter rispondere meglio alle domande in futuro includendo guide di piano con query di tipo CTE a cui si fa riferimento più volte per superare alcune stranezze CTE di SQL Server.
Non oggi. Le espressioni di tabella comune (CTE) non ricorsive vengono trattate come definizioni di vista in linea ed espanse nella struttura della query logica in ogni posizione a cui vengono referenziate (proprio come le definizioni di vista normali) prima dell'ottimizzazione. L'albero logico per la tua query è:
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
Notare le due ancore di visualizzazione e le sei chiamate alla funzione intrinseca newid
prima di iniziare l'ottimizzazione. Tuttavia, molte persone ritengono che l'ottimizzatore dovrebbe essere in grado di identificare che i sottoalberi espansi erano originariamente un singolo oggetto referenziato e semplificare di conseguenza. Sono state inoltre presentate diverse richieste Connect per consentire la materializzazione esplicita di una tabella CTE o derivata.
Un'implementazione più generale consentirebbe all'ottimizzatore di prendere in considerazione la materializzazione di espressioni comuni arbitrarie per migliorare le prestazioni ( CASE
con una subquery è un altro esempio in cui oggi possono verificarsi problemi ). Microsoft Research ha pubblicato un documento (PDF) su questo nel 2007, anche se fino ad oggi non è stato implementato. Per il momento, siamo limitati alla materializzazione esplicita usando cose come variabili di tabella e tabelle temporanee.
SQLKiwi ha menzionato l'elaborazione di piani in SSIS, esiste un modo o uno strumento utile per fornire un buon piano per SQL Server?
Questo era solo un pio desiderio da parte mia, e andò ben oltre l'idea di modificare le guide dei piani. È possibile, in linea di principio, scrivere uno strumento per manipolare direttamente l'XML del piano di spettacolo, ma senza una strumentazione di ottimizzazione specifica l'utilizzo dello strumento sarebbe probabilmente un'esperienza frustrante per l'utente (e lo sviluppatore arriva a pensarci).
Nel particolare contesto di questa domanda, tale strumento non sarebbe ancora in grado di materializzare i contenuti CTE in un modo che potrebbe essere utilizzato da più consumatori (per alimentare entrambi gli input nel cross join in questo caso). L'ottimizzatore e il motore di esecuzione supportano spool multi-consumatore, ma solo per scopi specifici, nessuno dei quali potrebbe essere fatto applicare a questo esempio particolare.
Anche se non sono sicuro, ho la sensazione abbastanza forte che RelOps possa essere seguito (Nested Loop, Lazy Spool) anche se la query non è esattamente la stessa del piano, ad esempio se hai aggiunto 4 e 5 al CTE , continua ancora a utilizzare lo stesso piano (apparentemente - testato su SQL Server 2012 RTM Express).
C'è una ragionevole quantità di flessibilità qui. L'ampia forma del piano XML viene utilizzata per guidare la ricerca di un piano finale (sebbene molti attributi siano completamente ignorati, ad esempio il tipo di partizionamento negli scambi) e anche le normali regole di ricerca siano notevolmente allentate. Ad esempio, la potatura anticipata di alternative basata su considerazioni di costo è disabilitata, è consentita l'introduzione esplicita di join incrociati e le operazioni scalari vengono ignorate.
Esistono troppi dettagli da approfondire, ma il posizionamento di filtri e scalari di calcolo non può essere forzato e i predicati del modulo column = value
sono generalizzati, quindi un piano contenente X = 1
o X = @X
può essere applicato a una query contenente X = 502
o X = @Y
. Questa particolare flessibilità può essere di grande aiuto nel trovare un piano naturale per forzare.
Nell'esempio specifico, Union All costante può sempre essere implementato come scansione costante; il numero di input nell'Unione Tutto non ha importanza.