In het geval van een INNER JOIN of een tabel aan de linkerkant in een LEFT JOIN, zal de optimizer in veel gevallen ontdekken dat het beter is om eerst een filter uit te voeren (hoogste selectiviteit) voordat daadwerkelijk welk type fysieke join dan ook wordt uitgevoerd - dus er zijn duidelijk fysieke volgorde van bewerkingen die beter zijn.
Tot op zekere hoogte kun je dit soms beheersen (of verstoren) met je SQL, bijvoorbeeld met aggregaten in subquery's.
De logische volgorde van het verwerken van de beperkingen in de query kan alleen worden getransformeerd volgens bekende invariante transformaties.
Dus:
SELECT *
FROM a
INNER JOIN b
ON a.id = b.id
WHERE a.something = something
AND b.something = something
is nog steeds logisch gelijk aan:
SELECT *
FROM a
INNER JOIN b
ON a.id = b.id
AND a.something = something
AND b.something = something
en ze zullen over het algemeen hetzelfde uitvoeringsplan hebben.
Aan de andere kant:
SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
WHERE a.something = something
AND b.something = something
is NIET gelijk aan:
SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
AND a.something = something
AND b.something = something
en dus gaat de optimizer ze niet omzetten in hetzelfde uitvoeringsplan.
De optimizer is erg slim en kan dingen behoorlijk succesvol verplaatsen, inclusief samenvouwende weergaven en inline tabelwaardefuncties, en zelfs dingen met redelijk succes door bepaalde soorten aggregaten duwen.
Wanneer u SQL schrijft, moet deze doorgaans begrijpelijk, onderhoudbaar en correct zijn. Wat betreft de efficiëntie bij de uitvoering, als de optimizer moeite heeft om de declaratieve SQL om te zetten in een uitvoeringsplan met acceptabele prestaties, kan de code soms worden vereenvoudigd of kunnen geschikte indexen of hints worden toegevoegd of opgesplitst in stappen die moeten sneller presteren - allemaal in opeenvolgende volgordes van invasiviteit.