Im Falle eines INNER JOIN oder einer Tabelle auf der linken Seite in einem LEFT JOIN wird der Optimierer in vielen Fällen feststellen, dass es besser ist, zuerst eine Filterung durchzuführen (höchste Selektivität), bevor er tatsächlich irgendeine Art von physischem Join durchführt - also dort sind offensichtlich physische Reihenfolge der Operationen, die besser sind.
Bis zu einem gewissen Grad können Sie dies manchmal mit Ihrem SQL steuern (oder stören), z. B. mit Aggregaten in Unterabfragen.
Die logische Reihenfolge der Verarbeitung der Einschränkungen in der Abfrage kann nur gemäß bekannten invarianten Transformationen transformiert werden.
Also:
SELECT *
FROM a
INNER JOIN b
ON a.id = b.id
WHERE a.something = something
AND b.something = something
ist immer noch logisch äquivalent zu:
SELECT *
FROM a
INNER JOIN b
ON a.id = b.id
AND a.something = something
AND b.something = something
und sie haben im Allgemeinen den gleichen Ausführungsplan.
Andererseits:
SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
WHERE a.something = something
AND b.something = something
ist NICHT gleichbedeutend mit:
SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
AND a.something = something
AND b.something = something
und daher wird der Optimierer sie nicht in denselben Ausführungsplan umwandeln.
Der Optimierer ist sehr schlau und in der Lage, Dinge ziemlich erfolgreich zu bewegen, einschließlich zusammenbrechender Ansichten und Inline-Tabellenwertfunktionen, sowie sogar ziemlich erfolgreich Dinge nach unten durch bestimmte Arten von Aggregaten zu schieben.
Wenn Sie SQL schreiben, muss es normalerweise verständlich, wartbar und korrekt sein. Wenn der Optimierer Schwierigkeiten hat, das deklarative SQL in einen Ausführungsplan mit akzeptabler Leistung umzuwandeln, kann der Code manchmal vereinfacht oder entsprechende Indizes oder Hinweise hinzugefügt oder in Schritte unterteilt werden, die sollten schneller durchführen - alles in aufeinanderfolgenden Reihenfolgen der Invasivität.