Tabellenausdrücke in der FROM-Klausel einer
        Abfrage werden in vielen Fällen vereinfacht.
      
Auf der Parserebene werden Abfragen mit rechten äußeren Join-Operationen in gleichwertige Abfragen konvertiert, die nur Left-Join-Operationen enthalten. Im Allgemeinen erfolgt die Konvertierung auf der Basis der folgenden Regel:
(T1, ...) RIGHT JOIN (T2,...) ON P(T1,...,T2,...) = (T2, ...) LEFT JOIN (T1,...) ON P(T1,...,T2,...).
        Alle inneren Join-Ausdrücke der Form T1 INNER JOIN T2
        ON P(T1,T2) werden durch die Liste
        T1,T2 ersetzt, und
        P(T1,T2) wird als Konjunkt mit der
        WHERE-Bedingung (oder mit der Join-Bedingung
        des einbettenden Joins, sofern vorhanden) verknüpft.
      
Wenn der Optimierer Pläne für Join-Abfragen mit einer äußeren Join-Operation auswertet, berücksichtigt er nur diejenigen Pläne, bei denen bei einer solchen Operation zunächst auf die äußeren und erst dann auf die inneren Tabellen zugegriffen wird. Die Optimiereroptionen sind eingeschränkt, weil nur solche Pläne uns die Ausführung von Abfragen mit äußeren Join-Operationen über das Schema mit verschachtelten Schleifen gestatten.
Angenommen, wir haben eine Abfrage folgenden Aussehens:
SELECT * T1 LEFT JOIN T2 ON P1(T1,T2) WHERE P(T1,T2) AND R(T2)
        Hierbei schränkt R(T2) die Anzahl passender
        Datensätze aus der Tabelle T2 erheblich ein.
        Wenn wir die Abfrage in ihrer ursprünglichen Form ausgeführt
        hätten, hätte der Optimierer keine andere Chance gehabt, als
        zuerst auf die Tabelle T1 und erst dann auf
        T2 zuzugreifen. Dies hätte einen sehr
        ineffizienten Ausführungsplan zur Folge gehabt.
      
        Glücklicherweise wandelt MySQL eine solche Abfrage in eine
        Abfrage ohne äußere Join-Operation um, wenn die
        WHERE-Bedingung nullabweisend wird. Eine
        Bedingung heißt nullabweisend für eine äußere
        Join-Operation, wenn sie für jeden
        NULL-ergänzten Datensatz, der für die
        Operation erstellt wurde, stets FALSE oder
        UNKNOWN ist.
      
Betrachten Sie folgenden äußeren Join:
T1 LEFT JOIN T2 ON T1.A=T2.A
Für ihn sind Bedingungen wie die folgenden nullabweisend:
T2.B IS NOT NULL, T2.B > 3, T2.C <= T1.C, T2.B < 2 OR T2.C > 1
Bedingungen wie die folgenden sind hingegen nicht nullabweisend:
T2.B IS NULL, T1.B < 3 OR T2.B IS NOT NULL, T1.B < 3 OR T2.B > 3
Die allgemeinen Regeln zur Überprüfung, ob eine Bedingung für einen äußeren Join nullabweisend ist oder nicht, sind recht einfach. Eine Bedingung ist nullabweisend, wenn sie
            die Form A IS NOT NULL hat, wobei
            A ein Attribut einer der inneren Tabellen
            ist,
          
            ein Prädikat ist, das eine innere Tabelle referenziert, die
            UNKNOWN ist, wenn eines ihrer Argumente
            NULL ist,
          
eine Konjunktion mit einer nullabweisenden Bedingung als Konjunkt ist,
eine Disjunktion nullabweisender Bedingungen ist.
Eine Bedingung kann für eine äußere Join-Operation nullabweisend sein und gleichzeitig für eine andere nicht. Betrachten Sie folgende Abfrage:
SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.A
                 LEFT JOIN T3 ON T3.B=T1.B
  WHERE T3.C > 0
        Hier ist die WHERE-Bedingung für die zweite
        äußere Join-Operation nullabweisend, nicht jedoch für die
        erste.
      
        Wenn die WHERE-Bedingung für eine äußere
        Join-Operation in einer Abfrage nullabweisend ist, wird die
        äußere Join-Operation durch eine innere Join-Operation
        ersetzt.
      
So wird etwa obige Abfrage durch die folgende ersetzt:
SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.A
                 INNER JOIN T3 ON T3.B=T1.B
  WHERE T3.C > 0
        Für die ursprüngliche Abfrage würde der Optimierer Pläne
        auswerten, die mit der Zugriffsreihenfolge
        T1,T2,T3 kompatibel wären. Für die
        ersetzende Abfrage wird außerdem die Zugriffssequenz
        T3,T1,T2 in Betracht gezogen.
      
Eine Konvertierung einer äußeren Join-Operation kann eine Konvertierung einer anderen derartigen Operation auslösen. Betrachten Sie folgende Abfrage:
SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.A
                 LEFT JOIN T3 ON T3.B=T2.B
  WHERE T3.C > 0
Diese wird in die folgende Abfrage konvertiert:
SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.A
                 INNER JOIN T3 ON T3.B=T2.B
  WHERE T3.C > 0
Diese wiederum ist äquivalent mit dieser Abfrage:
SELECT * FROM (T1 LEFT JOIN T2 ON T2.A=T1.A), T3 WHERE T3.C > 0 AND T3.B=T2.B
        Nun kann die verbleibende äußere Join-Operation ebenfalls
        durch einen inneren Join ersetzt werden, weil die Bedingung
        T3.B=T2.B nullabweisend ist und wir eine
        Abfrage erhalten, die überhaupt keine äußeren Joins enthält:
      
SELECT * FROM (T1 INNER JOIN T2 ON T2.A=T1.A), T3 WHERE T3.C > 0 AND T3.B=T2.B
Manchmal gelingt es, eine eingebettete äußere Join-Operation zu ersetzen, aber der einbettende äußere Join kann nicht konvertiert werden. Betrachten Sie folgende Abfrage:
SELECT * FROM T1 LEFT JOIN
              (T2 LEFT JOIN T3 ON T3.B=T2.B)
              ON T2.A=T1.A
  WHERE T3.C > 0
Sie wird wie folgt konvertiert:
SELECT * FROM T1 LEFT JOIN
              (T2 INNER JOIN T3 ON T3.B=T2.B)
              ON T2.A=T1.A
  WHERE T3.C > 0,
Dies lässt sich nur in einer Form umschreiben, die nach wie vor die einbettende äußere Join-Operation enthält:
SELECT * FROM T1 LEFT JOIN
              (T2,T3)
              ON (T2.A=T1.A AND T3.B=T2.B)
  WHERE T3.C > 0.
        Wenn Sie versuchen, eine eingebettete äußere Join-Operation zu
        konvertieren, dann müssen Sie die Join-Bedingung für den
        einbettenden äußeren Join gemeinsam mit der
        WHERE-Bedingung berücksichtigen. Betrachten
        Sie folgende Abfrage:
      
SELECT * FROM T1 LEFT JOIN
              (T2 LEFT JOIN T3 ON T3.B=T2.B)
              ON T2.A=T1.A AND T3.C=T1.C
  WHERE T3.D > 0 OR T1.D > 0
        Hier ist die WHERE-Bedingung für den
        eingebetteten äußeren Join nicht nullabweisend, wohl aber die
        Join-Bedingung des einbettenden äußeren Joins
        T2.A=T1.A AND T3.C=T1.C.
        Insofern kann die Abfrage wie folgt konvertiert werden:
      
SELECT * FROM T1 LEFT JOIN
              (T2, T3)
              ON T2.A=T1.A AND T3.C=T1.C AND T3.B=T2.B
  WHERE T3.D > 0 OR T1.D > 0
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.

