Normalerweise erstelle ich Planhinweise, indem ich zuerst eine Abfrage erstelle, die den richtigen Plan verwendet, und diese dann in die ähnliche Abfrage kopiere, die dies nicht tut. Dies ist jedoch manchmal schwierig, insbesondere wenn die Abfrage nicht genau gleich ist. Was ist der richtige Weg, um Planungsleitfäden von Grund auf neu zu erstellen?
SQLKiwi hat das Erstellen von Plänen in SSIS erwähnt. Gibt es eine Möglichkeit oder ein nützliches Tool, um beim Erstellen eines guten Plans für SQL Server zu helfen?
Die spezifische fragliche Instanz ist dieser CTE: SQLFiddle
with cte(guid,other) as (
select newid(),1 union all
select newid(),2 union all
select newid(),3)
select a.guid, a.other, b.guid guidb, b.other otherb
from cte a
cross join cte b
order by a.other, b.other;
Gibt es ANY Art und Weise das Ergebnis kommt mit genau drei verschieden zu machen guid
s und nicht mehr? Ich hoffe, dass wir in Zukunft Fragen besser beantworten können, indem wir Planungshandbücher mit CTE-Abfragen einbeziehen, auf die mehrmals verwiesen wird, um einige SQL Server-CTE-Macken zu überwinden.
quelle
Antworten:
Nicht heute. Nicht rekursive allgemeine Tabellenausdrücke (Common Table Expressions, CTEs) werden als Definitionen der Inline-Ansicht behandelt und vor der Optimierung an jeder Stelle, auf die verwiesen wird (genau wie bei regulären Ansichtsdefinitionen), in die logische Abfragestruktur erweitert. Der logische Baum für Ihre Abfrage lautet:
Beachten Sie die beiden View-Anker und die sechs Aufrufe der intrinsischen Funktion,
newid
bevor mit der Optimierung begonnen wird. Trotzdem sind viele Leute der Meinung, dass der Optimierer in der Lage sein sollte, zu identifizieren, dass die erweiterten Teilbäume ursprünglich ein einzelnes referenziertes Objekt waren, und dies entsprechend zu vereinfachen. Es gab auch mehrere Connect-Anforderungen , um die explizite Materialisierung eines CTE oder einer abgeleiteten Tabelle zu ermöglichen.Bei einer allgemeineren Implementierung sollte der Optimierer erwägen, beliebige allgemeine Ausdrücke zu materialisieren, um die Leistung zu verbessern (
CASE
eine Unterabfrage ist ein weiteres Beispiel, bei dem heute Probleme auftreten können). Microsoft Research veröffentlichte bereits 2007 ein Papier (PDF) zu diesem Thema, das bislang jedoch nicht implementiert wurde. Derzeit beschränken wir uns auf die explizite Materialisierung mit Tabellenvariablen und temporären Tabellen.Dies war nur ein Wunschdenken von meiner Seite und ging weit über die Idee der Änderung von Planungsleitfäden hinaus. Grundsätzlich ist es möglich, ein Tool zur direkten Bearbeitung von Showplan-XML zu schreiben, aber ohne spezielle Optimierungsinstrumente wäre die Verwendung des Tools wahrscheinlich eine frustrierende Erfahrung für den Benutzer (und der Entwickler wird darüber nachdenken).
Im speziellen Kontext dieser Frage wäre ein solches Tool immer noch nicht in der Lage, die CTE-Inhalte auf eine Weise zu materialisieren, die von mehreren Verbrauchern verwendet werden könnte (um in diesem Fall beide Eingaben dem Cross-Join zuzuführen). Das Optimierungs- und Ausführungsmodul unterstützt Spools für mehrere Konsumenten, jedoch nur für bestimmte Zwecke - von denen keines für dieses bestimmte Beispiel geeignet sein kann.
Hier besteht ein angemessenes Maß an Flexibilität. Die breite Form des XML-Plans wird verwendet, um die Suche nach einem endgültigen Plan zu leiten (obwohl viele Attribute vollständig ignoriert werden, z. B. der Partitionierungstyp bei Börsen), und die normalen Suchregeln werden ebenfalls erheblich gelockert. Beispielsweise wird das vorzeitige Bereinigen von Alternativen aus Kostengründen deaktiviert, die explizite Einführung von Cross-Joins ist zulässig, und skalare Operationen werden ignoriert.
Es gibt zu viele Details in in die Tiefe zu gehen, aber die Platzierung der Filter und Compute Skalare kann nicht erzwungen werden, und Prädikate der Form
column = value
verallgemeinert so ein Plan enthaltenX = 1
oderX = @X
kann auf eine Abfrage angewendet werden , enthaltenX = 502
oderX = @Y
. Diese besondere Flexibilität kann bei der Suche nach einem natürlichen Plan für die Erzwingung von Gewalt sehr hilfreich sein.Im konkreten Beispiel kann die Konstante Union All immer als Konstantenscan implementiert werden. Die Anzahl der Eingänge in die Union All spielt keine Rolle.
quelle
Es gibt keine Möglichkeit (SQL Server-Versionen bis 2012), eine einzelne Spool für beide Vorkommen des CTE erneut zu verwenden. Details finden Sie in der Antwort von SQLKiwi. Weiter unten gibt es zwei Möglichkeiten, den CTE zweimal zu materialisieren, was für die Art der Abfrage unvermeidbar ist. Beide Optionen führen zu einer eindeutigen Netto-Guid-Anzahl von 6.
Der Link von Martins Kommentar zu Quassnois Site in einem Blog über den Plan, einen CTE zu leiten, war eine teilweise Inspiration für diese Frage. Es beschreibt eine Möglichkeit, einen CTE für den Zweck einer korrelierten Unterabfrage zu materialisieren, auf die nur einmal verwiesen wird, obwohl die Korrelation dazu führen kann, dass sie mehrmals ausgewertet wird. Dies gilt nicht für die Abfrage in der Frage.
Option 1 - Planungshandbuch
Ausgehend von der Antwort von SQLKiwi habe ich den Leitfaden auf ein Minimum reduziert, das immer noch funktioniert. Beispielsweise
ConstantScan
listen die Knoten nur zwei Skalaroperatoren auf, die auf eine beliebige Anzahl erweitert werden können.Option 2 - Remote-Scan
Durch Erhöhen des Abfrageaufwands und Einführen eines Fernscans wird das Ergebnis erzielt.
quelle
Im Ernst, Sie können XML-Ausführungspläne nicht von Grund auf neu schneiden. Ihre Erstellung mit SSIS ist Science-Fiction. Ja, es ist alles XML, aber sie stammen aus verschiedenen Universen. Wenn er sich Pauls Blog zu diesem Thema ansieht , sagt er "viel in der Weise, wie es SSIS erlaubt ...", also haben Sie möglicherweise falsch verstanden? Ich glaube nicht, dass er sagt "Verwenden Sie SSIS, um Pläne zu erstellen", sondern "Wäre es nicht großartig, wenn Sie Pläne mit einer Drag & Drop-Oberfläche wie SSIS erstellen könnten ". Für eine sehr einfache Abfrage könnte man das vielleicht gerade noch schaffen, aber es ist eine Strecke, möglicherweise sogar eine Zeitverschwendung. Beschäftigte Arbeit, könnte man sagen.
Wenn ich einen Plan für einen USE PLAN-Hinweis oder eine Plananleitung erstelle, habe ich einige Ansätze. Beispielsweise kann ich Datensätze aus Tabellen entfernen (z. B. auf einer Kopie der Datenbank), um die Statistik zu beeinflussen und den Optimierer zu einer anderen Entscheidung zu bewegen. Ich habe auch Tabellenvariablen anstelle der gesamten Tabelle in der Abfrage verwendet, sodass das Optimierungsprogramm davon ausgeht, dass jede Tabelle 1 Datensatz enthält. Ersetzen Sie dann im generierten Plan alle Tabellenvariablen durch die ursprünglichen Tabellennamen und tauschen Sie sie als Plan aus. Eine andere Möglichkeit wäre, die WITH STATS_STREAM-Option von UPDATE STATISTICS zu verwenden, um Statistiken zu fälschen. Dies ist die Methode, die beim Klonen von Nur-Statistik-Kopien von Datenbanken verwendet wird, z
Ich habe in der Vergangenheit einige Zeit mit XML-Ausführungsplänen verbracht und festgestellt, dass SQL am Ende einfach "Ich benutze das nicht" lautet und die Abfrage so ausführt, wie es ohnehin sein soll.
Für Ihr spezielles Beispiel sind Sie sich sicher bewusst, dass Sie die Zeilenanzahl 3 oder TOP 3 in der Abfrage verwenden könnten, um dieses Ergebnis zu erhalten, aber ich denke, das ist nicht Ihr Punkt. Die richtige Antwort wäre wirklich: Verwenden Sie eine temporäre Tabelle. Ich würde dem zustimmen:) Eine falsche Antwort wäre: "Verbringen Sie Stunden oder Tage damit, Ihren eigenen benutzerdefinierten XML-Ausführungsplan zu zerschneiden, und versuchen Sie, den Optimierer dazu zu bringen, eine langsame Spule für den CTE zu erstellen, die möglicherweise ohnehin nicht funktioniert. Das würde schlau aussehen wäre aber auch unmöglich zu pflegen ".
Ich versuche nicht, dort unkonstruktiv zu sein, nur meine Meinung - hoffe, das hilft.
quelle
Schließlich gibt es in SQL 2016 CTP 3.0 eine Art von:)
Mit dem von Dmitry Pilugin hier beschriebenen Ablaufverfolgungsflag und den erweiterten Ereignissen können Sie (etwas willkürlich) drei eindeutige Guids aus den Zwischenstadien der Abfrageausführung herausfischen.
NB Dieser Code ist NICHT für die Produktion oder ernsthafte Verwendung in Bezug auf das Forcen von CTE- Plänen gedacht, sondern lediglich für einen unbeschwerten Blick auf eine neue Ablaufverfolgungsflagge und eine andere Vorgehensweise:
Getestet mit Version (CTP3.2) - 13.0.900.73 (x64), nur zum Spaß.
quelle
Ich habe festgestellt, dass Traceflag 8649 (Force Parallel Plan) dieses Verhalten für die linke Guid-Spalte in meinen Instanzen 2008, R2 und 2012 induziert hat. Ich musste das Flag in SQL 2005 nicht verwenden, in dem sich der CTE korrekt verhalten hat. Ich habe versucht, den in SQL 2005 generierten Plan in den höheren Instanzen zu verwenden, aber er konnte nicht validiert werden.
Entweder unter Verwendung des Hinweises, unter Verwendung eines Planleitfadens einschließlich des Hinweises oder unter Verwendung des von der Abfrage generierten Plans mit dem Hinweis in einem NUTZUNGSPLAN usw. hat alles funktioniert.
quelle