Frage

Gibt es einen Effizienzunterschied zwischen einem expliziten und einem impliziten Inner Join?Zum Beispiel:

SELECT * FROM
table a INNER JOIN table b
ON a.id = b.id;

vs.

SELECT a.*, b.*
FROM table a, table b
WHERE a.id = b.id;
War es hilfreich?

Lösung

In Bezug auf die Leistung sind sie genau gleich (zumindest in SQL Server).

PS:Seien Sie sich bewusst, dass die IMPLICIT OUTER JOIN Die Syntax ist seit SQL Server 2005 veraltet.(Der IMPLICIT INNER JOIN Die in der Frage verwendete Syntax wird weiterhin unterstützt.)

Abschaffung der JOIN-Syntax „Old Style“:Nur eine Teilsache

Andere Tipps

Persönlich bevorzuge ich die Join-Syntax, da sie klarer macht, dass die Tabellen verknüpft werden und wie sie verknüpft werden.Versuchen Sie, größere SQL-Abfragen zu vergleichen, bei denen Sie aus 8 verschiedenen Tabellen auswählen und dort viele Filtermöglichkeiten haben.Durch die Verwendung der Join-Syntax trennen Sie die Teile, in denen die Tabellen verknüpft werden, in den Teil, in dem Sie die Zeilen filtern.

Unter MySQL 5.1.51 haben beide Abfragen identische Ausführungspläne:

mysql> explain select * from table1 a inner join table2 b on a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.02 sec)

mysql> explain select * from table1 a, table2 b where a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.00 sec)

table1 hat 166208 Zeilen; table2 hat etwa 1000 Zeilen.

Dies ist ein sehr einfacher Fall;Es beweist keineswegs, dass der Abfrageoptimierer in einem komplizierteren Fall nicht durcheinander geraten und unterschiedliche Pläne generieren würde.

Die zweite Syntax birgt die unerwünschte Möglichkeit eines Cross-Joins:Sie können dem FROM-Teil Tabellen ohne entsprechende WHERE-Klausel hinzufügen.Dies gilt als schädlich.

Die erste Antwort, die Sie gegeben haben, verwendet die sogenannte ANSI-Join-Syntax, die andere ist gültig und funktioniert in jeder relationalen Datenbank.

Ich stimme grom zu, dass Sie die ANSI-Join-Syntax verwenden sollten.Wie sie sagten, liegt der Hauptgrund in der Klarheit.Anstatt eine Where-Klausel mit vielen Prädikaten zu haben, von denen einige Tabellen verknüpfen und andere die zurückgegebenen Zeilen mit der ANSI-Verknüpfungssyntax einschränken, machen Sie unmissverständlich klar, welche Bedingungen zum Verknüpfen Ihrer Tabellen verwendet werden und welche zur Einschränkung verwendet werden Ergebnisse.

@lomaxx:Zur Klarstellung: Ich bin mir ziemlich sicher, dass beide oben genannten Syntaxen von SQL Serv 2005 unterstützt werden.Die folgende Syntax wird jedoch NICHT unterstützt

select a.*, b.*  
from table a, table b  
where a.id *= b.id;

Insbesondere wird der Outer-Join (*=) nicht unterstützt.

In Bezug auf die Leistung sind sie genau gleich (zumindest in SQL Server). Beachten Sie jedoch, dass diese Join-Syntax veraltet ist und von SQL Server 2005 standardmäßig nicht unterstützt wird.

Ich denke, Sie denken an die veralteten Operatoren *= und =* vs.„äußerer Join“.

Ich habe gerade die beiden angegebenen Formate getestet und sie funktionieren ordnungsgemäß in einer SQL Server 2008-Datenbank.In meinem Fall lieferten sie identische Ausführungspläne, aber ich konnte nicht mit Sicherheit sagen, dass dies immer wahr sein würde.

Bei einigen Datenbanken (insbesondere Oracle) kann die Reihenfolge der Verknüpfungen einen großen Einfluss auf die Abfrageleistung haben (wenn mehr als zwei Tabellen vorhanden sind).Bei einer Anwendung hatten wir teilweise einen Unterschied von buchstäblich zwei Größenordnungen.Durch die Verwendung der Inner-Join-Syntax haben Sie die Kontrolle darüber – vorausgesetzt, Sie verwenden die richtige Hints-Syntax.

Sie haben nicht angegeben, welche Datenbank Sie verwenden, aber die Wahrscheinlichkeit deutet auf SQL Server oder MySQL hin, wo es keinen wirklichen Unterschied macht.

Wie Leigh Caldwell festgestellt hat, kann der Abfrageoptimierer unterschiedliche Abfragepläne basierend auf dem funktionalen Erscheinungsbild derselben SQL-Anweisung erstellen.Weitere Informationen hierzu finden Sie in den folgenden beiden Blogbeiträgen:

Ein Beitrag vom Oracle Optimizer Team

Ein weiterer Beitrag aus dem Blog „Structured Data“.

Ich hoffe, Sie finden das interessant.

Was die Leistung betrifft, sollte es keinen Unterschied machen.Die explizite Join-Syntax erscheint mir sauberer, da sie die Beziehungen zwischen Tabellen in der from-Klausel klar definiert und die where-Klausel nicht überfüllt.

Meiner Erfahrung nach führt die Verwendung der Cross-Join-with-a-Where-Clause-Syntax häufig zu einem hirngeschädigten Ausführungsplan, insbesondere wenn Sie ein Microsoft SQL-Produkt verwenden.Die Art und Weise, wie SQL Server beispielsweise versucht, die Anzahl der Tabellenzeilen zu schätzen, ist grauenhaft.Durch die Verwendung der Inner-Join-Syntax haben Sie eine gewisse Kontrolle darüber, wie die Abfrage ausgeführt wird.Aus praktischer Sicht müssen Sie sich angesichts der atavistischen Natur der aktuellen Datenbanktechnologie für den Inner Join entscheiden.

Der Unterschied zwischen den beiden besteht im Wesentlichen darin, dass das eine auf die alte Art und das andere auf die moderne Art geschrieben ist.Persönlich bevorzuge ich das moderne Skript mit den Definitionen „inner“, „left“, „outer“ und „right“, da diese erklärender sind und den Code besser lesbar machen.

Beim Umgang mit inneren Verknüpfungen gibt es auch keinen wirklichen Unterschied in der Lesbarkeit. Allerdings könnte es kompliziert werden, wenn man mit linken und rechten Verknüpfungen umgeht, da man bei der älteren Methode etwa Folgendes erhalten würde:

SELECT * 
FROM table a, table b
WHERE a.id = b.id (+);

Das Obige ist die alte Art und Weise, wie ein Left-Join geschrieben wird, im Gegensatz zu der folgenden:

SELECT * 
FROM table a 
LEFT JOIN table b ON a.id = b.id;

Wie Sie visuell sehen können, sorgt die moderne Art und Weise, wie das Skript geschrieben ist, dafür, dass die Abfrage besser lesbar ist.(Das Gleiche gilt übrigens auch für Right-Joins, während es für Outer-Joins etwas komplizierter ist.)

Zurück zum Grundprinzip: Es macht für den SQL-Compiler keinen Unterschied, wie die Abfrage geschrieben wird, da er sie auf die gleiche Weise behandelt.Ich habe in Oracle-Datenbanken eine Mischung aus beidem gesehen, in die viele Leute geschrieben haben, sowohl ältere als auch jüngere.Auch hier kommt es darauf an, wie lesbar das Skript ist und mit welchem ​​Team Sie entwickeln.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top