1125 Stimmen

INNER JOIN ON vs WHERE-Klausel

Der Einfachheit halber nehmen wir an, dass alle relevanten Felder NOT NULL .

Das können Sie tun:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1, table2
WHERE
    table1.foreignkey = table2.primarykey
    AND (some other conditions)

Oder aber:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1 INNER JOIN table2
    ON table1.foreignkey = table2.primarykey
WHERE
    (some other conditions)

Funktionieren diese beiden auf dieselbe Weise in MySQL ?

2 Stimmen

@Marco: hier ist es

2 Stimmen

32 Stimmen

Wenn ich es richtig verstanden habe, handelt es sich bei der ersten Variante um die implizite ANSI-SQL-89-Syntax und bei der zweiten Variante um die explizite ANSI-SQL-92-Join-Syntax. Beide führen in konformen SQL-Implementierungen zum gleichen Ergebnis und beide führen in gut gemachten SQL-Implementierungen zum gleichen Abfrageplan. Ich persönlich bevorzuge die SQL-89-Syntax, aber viele Leute bevorzugen die SQL-92-Syntax.

34voto

HLGEM Punkte 91543

Ich möchte auch darauf hinweisen, dass die Verwendung der älteren Syntax fehleranfälliger ist. Wenn Sie innere Verknüpfungen ohne eine ON-Klausel verwenden, erhalten Sie einen Syntaxfehler. Wenn Sie die ältere Syntax verwenden und eine der Verknüpfungsbedingungen in der Where-Klausel vergessen, erhalten Sie eine Kreuzverknüpfung. Die Entwickler beheben dies oft, indem sie das Schlüsselwort distinct hinzufügen (anstatt die Verknüpfung zu reparieren, da sie immer noch nicht erkennen, dass die Verknüpfung selbst fehlerhaft ist), was das Problem zwar scheinbar behebt, die Abfrage aber erheblich verlangsamt.

Wenn Sie in der alten Syntax eine Querverbindung haben, woher weiß der Wartungsbeauftragte dann, ob Sie eine solche beabsichtigt haben (es gibt Situationen, in denen Querverbindungen erforderlich sind) oder ob es sich um ein Versehen handelt, das behoben werden sollte?

Ich möchte Sie auf diese Frage hinweisen, um zu sehen, warum die implizite Syntax schlecht ist, wenn Sie linke Joins verwenden. Sybase *= nach Ansi Standard mit 2 verschiedenen äußeren Tabellen für dieselbe innere Tabelle

Außerdem ist der Standard, der explizite Verknüpfungen verwendet, über 20 Jahre alt, was bedeutet, dass die implizite Verknüpfungssyntax in diesen 20 Jahren veraltet war. Würden Sie Anwendungscode mit einer Syntax schreiben, die seit 20 Jahren veraltet ist? Warum sollten Sie Datenbankcode schreiben, der das tut?

16voto

Brent Baisley Punkte 710

Der SQL:2003-Standard hat einige Vorrangregeln geändert, so dass eine JOIN-Anweisung Vorrang vor einer "Komma"-Verknüpfung hat. Dies kann die Ergebnisse Ihrer Abfrage tatsächlich verändern, je nachdem, wie sie eingerichtet ist. Dies führte bei einigen Leuten zu Problemen, als MySQL 5.0.12 dazu überging, sich an den Standard zu halten.

In Ihrem Beispiel würden Ihre Abfragen also auf die gleiche Weise funktionieren. Aber wenn Sie eine dritte Tabelle hinzufügen: SELECT ... FROM table1, table2 JOIN table3 ON ... WHERE ...

Vor MySQL 5.0.12 wurden zuerst Tabelle1 und Tabelle2 verbunden, dann Tabelle3. Jetzt (ab 5.0.12) werden zuerst Tabelle2 und Tabelle3 verbunden, dann Tabelle1. Das ändert nicht immer die Ergebnisse, aber es kann sein, dass Sie es nicht einmal merken.

Ich verwende die "Komma"-Syntax nicht mehr und entscheide mich für Ihr zweites Beispiel. Es ist ohnehin viel lesbarer, da die JOIN-Bedingungen bei den JOINs stehen und nicht in einem separaten Abfrageabschnitt.

15voto

John Gietzen Punkte 47223

Sie haben eine andere, für den Menschen lesbare Bedeutung.

Je nach Abfrageoptimierer können sie jedoch für die Maschine die gleiche Bedeutung haben.

Sie sollten Ihren Code immer so gestalten, dass er lesbar ist.

Das heißt, wenn es sich um eine eingebaute Beziehung handelt, verwenden Sie die explizite Verknüpfung. Wenn Sie einen Abgleich mit schwach verwandten Daten vornehmen, verwenden Sie die Where-Klausel.

7voto

João Marcus Punkte 1570

Ich weiß, dass Sie von MySQL sprechen, aber trotzdem: In Oracle 9 würden explizite Joins und implizite Joins unterschiedliche Ausführungspläne erzeugen. AFAIK wurde das in Oracle 10+ gelöst: Es gibt keinen solchen Unterschied mehr.

4voto

Benzo Punkte 129

Die ANSI-Join-Syntax ist definitiv portabler.

Ich führe gerade ein Upgrade von Microsoft SQL Server durch, und ich möchte auch erwähnen, dass die =* und *= Syntax für äußere Joins in SQL Server nicht unterstützt wird (ohne Kompatibilitätsmodus) für SQL Server 2005 und später.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X