Bei einer mäßig komplexen Abfrage, die ich optimieren möchte, ist mir aufgefallen, dass das Entfernen der TOP n
Klausel den Ausführungsplan ändert. Ich hätte gedacht, dass, wenn eine Abfrage TOP n
das Datenbankmodul enthält , die Abfrage ausgeführt wird, wobei die TOP
Klausel ignoriert wird , und am Ende das Ergebnis auf die Anzahl n der angeforderten Zeilen reduziert wird. Der grafische Ausführungsplan scheint darauf hinzuweisen, dass dies der Fall ist - dies TOP
ist der "letzte" Schritt. Aber es scheint, dass mehr los ist.
Meine Frage ist, wie (und warum) sich eine TOP n-Klausel auf den Ausführungsplan einer Abfrage auswirkt.
Hier ist eine vereinfachte Version dessen, was in meinem Fall vor sich geht:
Die Abfrage stimmt mit Zeilen aus zwei Tabellen, A und B, überein.
Ohne die TOP
Klausel werden nach Schätzungen des Optimierers 19.000 Zeilen aus Tabelle A und 46.000 Zeilen aus Tabelle B zurückgegeben. Die tatsächliche Anzahl der zurückgegebenen Zeilen beträgt 16.000 für A und 13.000 für B. Diese beiden Ergebnismengen werden für a mit einer Hash-Übereinstimmung verknüpft Insgesamt 69 Zeilen (dann wird eine Sortierung angewendet). Diese Abfrage erfolgt sehr schnell.
Wenn ich hinzufüge, verwendet TOP 1001
der Optimierer keine Hash-Übereinstimmung. anstatt es sortiert zunächst die Ergebnisse aus Tabelle A (gleiche Schätzwert / Ist von 19k / 16k) und macht eine verschachtelte Schleife gegen Tabelle B Die geschätzte Anzahl der Zeilen für Tabelle B versteht sich nun auf 1, und das Merkwürdige ist , dass die TOP n
direkt die Auswirkungen geschätzte Anzahl von Ausführungen (Indexsuche) gegen B - es scheint immer 2n + 1 zu sein , oder in meinem Fall 2003. Diese Schätzung ändert sich entsprechend, wenn ich mich ändere TOP n
. Da dies ein verschachtelter Join ist, beträgt die tatsächliche Anzahl der Ausführungen 16.000 (die Anzahl der Zeilen aus Tabelle A), was die Abfrage verlangsamt.
Das eigentliche Szenario ist etwas komplexer, aber dies erfasst die Grundidee / das grundlegende Verhalten. Beide Tabellen werden mit Indexsuchen durchsucht. Dies ist die SQL Server 2008 R2 Enterprise Edition.
ORDER BY
Klausel. Hinzufügen vonTOP
Änderungen, wo im Plan diese Art auftritt, aber ich bin mehr besorgt darüber, wie sich dies auf die Anzahl der Ausführungen von Index-Suchvorgängen in Tabelle B auswirkt ... (natürlich können die beiden verwandt sein - ich weiß nicht)FAST num_rows
Abfragehinweis.Antworten:
Die Art und Weise, wie das oben Gesagte formuliert ist, lässt mich denken, dass Sie möglicherweise ein falsches Bild davon haben, wie eine Abfrage ausgeführt wird. Ein Operator in einem Abfrageplan ist kein Schritt (bei dem die vollständige Ergebnismenge eines vorherigen Schritts von der nächsten ausgewertet wird).
SQL Server verwendet ein Pipeline- Ausführungsmodell, bei dem jeder Operator Methoden wie Init () , GetRow () und Close () verfügbar macht . Wie der Name GetRow () andeutet, erstellt ein Operator bei Bedarf jeweils eine Zeile (wie vom übergeordneten Operator gefordert). Dies ist in der Online-Dokumentation für logische und physische Operatoren dokumentiert. Weitere Informationen finden Sie in meinem Blog-Beitrag Warum Abfragepläne rückwärts ausgeführt werden . Dieses zeilenweise Modell ist für die Erstellung einer fundierten Intuition für die Ausführung von Abfragen von entscheidender Bedeutung.
Einige logische Operationen wie
TOP
Semi-Joins und derFAST n
Abfragehinweis wirken sich auf die Art und Weise aus, wie das Abfrageoptimierungsprogramm Ausführungsplanalternativen kostet. Die Grundidee ist, dass eine mögliche Planform die ersten n Zeilen schneller zurückgibt als ein anderer Plan, der für die Rückgabe aller Zeilen optimiert wurde.Beispielsweise ist der Join mit indizierten verschachtelten Schleifen häufig der schnellste Weg, um eine kleine Anzahl von Zeilen zurückzugeben, obwohl der Hash- oder Merge-Join mit Scans bei größeren Mengen möglicherweise effizienter ist. Das Abfrageoptimierungsprogramm ermittelt diese Auswahlmöglichkeiten, indem es ein Zeilenziel an einem bestimmten Punkt in der logischen Betriebsstruktur festlegt.
Ein Zeilenziel ändert die Art und Weise, in der Alternativen für Abfragepläne berechnet werden. Das Wesentliche dabei ist, dass das Optimierungsprogramm zunächst jeden Operator so kalkuliert, als ob die gesamte Ergebnismenge erforderlich wäre, ein Zeilenziel an der entsprechenden Stelle festlegt und dann den Planbaum zurücksetzt, um die Anzahl der zu untersuchenden Zeilen zu schätzen um das Reihenziel zu erreichen.
Beispielsweise setzt eine Logik
TOP(10)
an einem bestimmten Punkt in der logischen Abfragestruktur ein Zeilenziel von 10. Die Kosten der Operatoren, die zum Zeilenziel führen, werden geändert, um abzuschätzen, wie viele Zeilen sie produzieren müssen, um das Zeilenziel zu erreichen. Diese Berechnung kann komplex werden, daher ist es einfacher, all dies anhand eines vollständig ausgearbeiteten Beispiels und kommentierter Ausführungspläne zu verstehen . Zeilenziele können mehr beeinflussen als die Auswahl des Verknüpfungstyps oder ob Suchvorgänge und Suchvorgänge gegenüber Scans bevorzugt werden. Mehr dazu hier .Wie immer unterliegt ein auf der Grundlage eines Zeilenziels ausgewählter Ausführungsplan den Argumentationsfähigkeiten des Optimierers und der Qualität der ihm bereitgestellten Informationen. Nicht jeder Plan mit einem Zeilenziel wird in der Praxis die erforderliche Anzahl von Zeilen schneller produzieren, sondern gemäß dem Kalkulationsmodell.
Wenn sich herausstellt, dass ein Zeilenzielplan nicht schneller ist, gibt es normalerweise Möglichkeiten, die Abfrage zu ändern oder dem Optimierer bessere Informationen bereitzustellen, sodass der natürlich ausgewählte Plan am besten ist. Welche Option in Ihrem Fall angemessen ist, hängt natürlich von den Details ab. Das Zeilenziel-Feature ist im Allgemeinen sehr effektiv (obwohl es einen Fehler gibt, auf den Sie achten müssen, wenn Sie es in parallelen Ausführungsplänen verwenden).
Ihre spezielle Anfrage und Ihr Plan sind möglicherweise nicht für eine detaillierte Analyse geeignet (stellen Sie auf jeden Fall einen tatsächlichen Ausführungsplan zur Verfügung, wenn Sie dies wünschen), aber hoffentlich können Sie mit den hier beschriebenen Ideen Fortschritte erzielen.
quelle
Wenn Sie TOP verwenden, sieht der Optimierer die Möglichkeit, weniger Arbeit zu erledigen. Wenn Sie nach 10 Zeilen fragen, besteht eine gute Chance, dass nicht der gesamte Satz verbraucht werden muss. So kann der TOP-Operator viel weiter nach rechts geschoben werden. Es fordert so lange Zeilen vom nächsten Operator (rechts von ihm) an, bis es genug empfangen hat.
Sie weisen darauf hin, dass die Abfrage ohne TOP die Daten ganz am Ende sortiert. Wenn die Engine im Voraus wissen könnte, wie viele Zeilen durch den Join erfüllt werden sollen, könnte sie sich für einen ähnlichen Plan entscheiden und das OBEN links positionieren. Da der Aufwand für ein Hash-Match jedoch relativ hoch ist und vermutlich keine Option für einen Merge-Join besteht, zieht das Optimierungsprogramm es möglicherweise vor, das TOP weiter rechts zu filtern.
Wenn Tabelle B abgefragt wird, wird jeweils eine einzelne Zeile abgerufen. Das ist der Grund, warum die Schätzung 1 lautet. Außerdem wird davon ausgegangen, dass diese Zeile in 50% der Fälle nur vorkommt. Es wird also 2n + 1 benötigt, um es zu finden.
quelle
TOP
Klausel zu tun ? Vielen Dank für Ihre Antwort (en) / Geduld.