Anti-Semi-Join Reordering
Spielt die Reihenfolge der Angaben in der Where-Klausel eine Rolle? In der Regel nicht, aber es gibt Ausnahmen.
Wie Conor Cunningham vor einiger Zeit bereits in seinem blog berichtete, kann der Optimizer allerhand "magische" Operationen und Umstellungen vornehmen. Eine Änderung der Reihenfolge der NOT EXISTS Klauseln, die sich im selben Bereich befinden, scheint aber im Code nicht vorgesehen zu sein.
Beispiel
Die beiden folgenden SQLs sind eigentlich identisch. Beide werden auf einen Full-Table-Scan der "großen Tabelle" hinauslaufen. Lediglich die Reihenfolge der NOT EXISTS Klauseln ist vertauscht. Die Ausführungspläne sehen entsprechend anders aus, da kein Reordering stattfindet.
SELECT *
FROM dbo.MeineDaten
WHERE MeineDaten_Lfdnr BETWEEN 700 AND 710
AND NOT EXISTS (SELECT *
FROM dbo.MeineDaten
WHERE MeineDaten_Lfdnr = 703)
AND NOT EXISTS( SELECT * FROM dbo.GrosseTabelle m WHERE m.GrosseTabelle_Wert LIKE '%abc%');
Und hier die vertauschte Where-Klausel
SELECT *
FROM dbo.MeineDaten
WHERE MeineDaten_Lfdnr BETWEEN 700 AND 710
AND NOT EXISTS( SELECT * FROM dbo.GrosseTabelle m WHERE m.GrosseTabelle_Wert LIKE '%abc%')
AND NOT EXISTS (SELECT *
FROM dbo.MeineDaten
WHERE MeineDaten_Lfdnr = 703);
Der Unterschied ist beachtlich. Während das erste Statement in ca. 3 Millisekunden fertig ist, da der Zugriff im ersten NOT EXISTS blitzschnell ist, braucht das zweite Statement satte 3500 Millisekunden.
Wie sollte man Abfragen codieren?
Die Antwort auf diese Frage sollte eigentlich immer lauten: So, dass andere Menschen diese auch verstehen können. Man selber wird auch dankbar sein, wenn man nach einem Jahr seinen eigenen Code noch versteht. Also logische Zusammenhänge auch in räumlicher Nähe codieren. Der Optimizer wird sich das schon zurecht biegen wie er es braucht.
Ausserdem ist ja auch der Optimizer von Menschen programmiert, die bestimmte Muster suchen und neu arangieren wollen.
Und wenn es mal nicht so klappt?
Dann sollte man einen Blick auf den Ausführungsplan werfen und sich bestenfalls daran erinnern, dass die Reihenfolge der Anti-Semi-Joins nicht unbedingt neu arrangiert wird und hier die selektivsten vielleicht doch am Anfang stehen sollten.
Aber wer weiß, zu was der Optimizer in Zukunft in der Lage sein wird? Zitat Conor: Also, remember that we do add rules each release, so don’t assume that we never do these rewrites. We like adding transformation rules in the engine.
Print article | This entry was posted by cmu on 09.05.12 at 09:58:00 . Follow any responses to this post through RSS 2.0. |