W przypadku INNER JOIN lub tabeli po lewej stronie w LEFT JOIN, w wielu przypadkach optymalizator stwierdzi, że lepiej jest najpierw przeprowadzić jakiekolwiek filtrowanie (najwyższa selektywność) przed faktycznym wykonaniem jakiegokolwiek fizycznego złączenia - tak więc to oczywiście fizyczna kolejność operacji, które są lepsze.
Do pewnego stopnia możesz czasami kontrolować to (lub ingerować) w swój SQL, na przykład za pomocą agregacji w podzapytaniach.
Logiczną kolejność przetwarzania ograniczeń w zapytaniu można przekształcić tylko zgodnie ze znanymi przekształceniami niezmiennymi.
A więc:
SELECT *
FROM a
INNER JOIN b
ON a.id = b.id
WHERE a.something = something
AND b.something = something
jest nadal logicznie odpowiednikiem:
SELECT *
FROM a
INNER JOIN b
ON a.id = b.id
AND a.something = something
AND b.something = something
i generalnie będą mieli ten sam plan wykonania.
Z drugiej strony:
SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
WHERE a.something = something
AND b.something = something
NIE jest równoznaczne z:
SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
AND a.something = something
AND b.something = something
więc optymalizator nie przekształci ich w ten sam plan wykonania.
Optymalizator jest bardzo sprytny i jest w stanie całkiem skutecznie przenosić elementy, w tym zwijanie widoków i wbudowane funkcje z wartościami tabelarycznymi, a nawet całkiem skutecznie przesuwać elementy w dół przez niektóre rodzaje agregatów.
Zazwyczaj, kiedy piszesz SQL, musi być zrozumiały, łatwy w utrzymaniu i poprawny. Jeśli chodzi o wydajność wykonywania, jeśli optymalizator ma trudności z przekształceniem deklaratywnego SQL w plan wykonania z akceptowalną wydajnością, kod może być czasem uproszczony lub można dodać odpowiednie indeksy lub wskazówki lub podzielić na kroki, które powinny wykonywać szybciej - wszystko w kolejnych rzędach inwazyjności.