it-swarm-eu.dev

SQL Server Join / wo Verarbeitungsreihenfolge

Nachdem ich Slow SQL Query gelesen hatte und nicht sicher war, wie ich optimieren soll, dachte ich über die allgemeine Leistung von Abfragen nach. Sicherlich müssen die Ergebnisse der ersten Tabelle (wenn andere Tabellen verbunden werden) vor dem Verbinden so klein wie möglich sein (innere Verknüpfungen für diese Frage), damit unsere Abfragen ein kleines bisschen schneller werden.

Beispiel, sollte dies:

SELECT *
FROM   ( SELECT * FROM table1 WHERE col = @val ) t
INNER JOIN table2 ON col = col2

Sei besser/schneller als:

SELECT *
FROM table1
INNER JOIN table2 ON col = col2
WHERE table1.col = @val

Meine Theorie lautet wie folgt (dies ist möglicherweise nicht die richtige Implementierung, ich versuche mich an ein internes SQL Server 2008-Buch zu erinnern, das ich gelesen habe (MSFT Press)):

  1. Der Abfrageprozessor erhält zuerst die linke Tabelle (Tabelle1)
  2. Tritt der zweiten Tabelle (Tabelle 2) bei und bildet ein kartesisches Produkt, bevor die erforderlichen Zeilen herausgefiltert werden (falls zutreffend).
  3. Führen Sie dann zuletzt die Klauseln WHERE, ORDER BY, GROUP BY, HAVING mit der Anweisung SEELCT aus.

Wenn also in Anweisung 1 oben die Tabelle kleiner ist, hat die SQL-Engine beim Bilden der kartesischen Produkte weniger Arbeit zu erledigen. Wenn Sie dann die where-Anweisung erreichen, haben Sie eine reduzierte Ergebnismenge, aus der im Speicher gefiltert werden soll.

Ich könnte so weit vom Ziel entfernt sein, dass es unwirklich ist. Wie ich schon sagte, es ist eine Theorie.

Ihre Gedanken?

Hinweis : Ich habe gerade erst an diese Frage gedacht und hatte noch keine Gelegenheit, selbst Tests durchzuführen.

Hinweis 2 : Als SQL Server markiert, da ich nicht weiß irgendetwas über die Implementierung von MySql usw. Bitte fühlen Sie trotzdem frei zu antworten/kommentieren

18
Stuart Blackler

Die logische Verarbeitung einer Abfrage erfolgt in MSDN (geschrieben vom Microsoft SQL Server-Team, nicht von Drittanbietern).

1. FROM
2. ON
3. JOIN
4. WHERE
5. GROUP BY
6. WITH CUBE or WITH ROLLUP
7. HAVING
8. SELECT
9. DISTINCT
10. ORDER BY
11. TOP

Darauf folgt eine abgeleitete Tabelle, die die äußere Abfrage erneut ausführt

Dies ist jedoch logisch : nicht tatsächlich . Unabhängig davon, wie SQL Server dies tatsächlich tut, wird diese Semantik berücksichtigt auf den Buchstaben. Der "tatsächliche" Wert wird vom Query Optimiser (QO) ermittelt, und Sie vermeiden das von Ihnen erwähnte Zwischenprodukt Cartesion.

Erwähnenswert ist, dass SQL deklarativ ist: Sie sagen "was" nicht "wie" wie bei einer prozeduralen/imperativen Programmierung (Java, .net). Die Aussage "das passiert vorher" ist in vielen Fällen falsch (z. B. Annahme von Kurzschlüssen oder L-zu-R-WHERE-Reihenfolge)

In Ihrem obigen Fall generiert die Qualitätssicherung denselben Plan, unabhängig davon, wie er strukturiert ist, da es sich um eine einfache Abfrage handelt.

Die Qualitätssicherung ist jedoch kostenbasiert und bei einer komplexen Abfrage kann es 2 Wochen dauern, bis der ideale Plan erstellt ist. Also macht es "gut genug", was eigentlich nicht ist.

Ihr erster Fall kann dem Optimierer also helfen, einen besseren Plan zu finden, da die logische Verarbeitungsreihenfolge für die beiden Abfragen unterschiedlich ist. Aber es kann nicht.

Ich habe diesen Trick unter SQL Server 2000 verwendet, um die Leistung bei Berichtsabfragen um das 60-fache zu verbessern. Wenn die Qualitätssicherung von Version zu Version verbessert wird, können diese Dinge besser geklärt werden.

Und das Buch, das Sie erwähnt haben: Es gibt Streit darüber
Siehe SO und die nachfolgenden Links: https://stackoverflow.com/q/3270338/27535

16
gbn

Eine SQL-Abfrage ist nicht prozeduraler Natur, es gibt keine Verarbeitung der Join-Operatoren von oben nach unten. Die Reihenfolge der Tabellen in Ihren Beispielabfragen hat keinen Einfluss auf Ausführungsplan , da sie logisch äquivalent sind und genau denselben Plan generieren.

Sie haben zwei der Optionen ausgewertet, die Abfrageoptimierer beim Generieren eines Plans für diese Abfrage berücksichtigen könnte. Der Hauptfaktor, der die Planauswahl beeinflusst, ist Statistik für die beteiligten Tabellen und Kosten für die Auswahl des Bedieners in Kandidatenplänen.

Ein sehr einfacher Join mit zwei Tabellen, wie in Ihrem Beispiel, kann mit einem von Hunderten verschiedener Ausführungspläne zufrieden sein. Der Optimierer entscheidet, wie Ihre Anfrage am besten beantwortet werden kann, indem er die Kosten dieser Pläne vergleicht.

Manchmal wird es falsch verstanden, und Sie können ihm helfen, bessere Entscheidungen zu treffen, indem Sie die Indizierung verbessern, Statistiken auf dem neuesten Stand halten und Hinweise anwenden. In sehr seltenen Fällen möchten Sie möglicherweise die Ausführungsreihenfolge mithilfe des Hinweises FORCE ORDER erzwingen. Dies sollte jedoch sparsam verwendet werden. Es ist ein Hammer, um eine Nuss zu knacken. Der Optimierer kann normalerweise dazu gebracht werden, bessere Pläne zu generieren, indem er bessere Informationen liefert.

6