Die folgenden SQL-Abfragen sind identisch:
SELECT column1, column2
FROM table1, table2
WHERE table1.id = table2.id;
SELECT column1, column2
FROM table1 JOIN table2
ON table1.id = table2.id;
Und mit Sicherheit ergeben sich auf jedem DBMS, das ich je ausprobiert habe, die gleichen Abfragepläne.
Aber ab und zu lese oder höre ich die Meinung, dass einer definitiv besser ist als der andere. Natürlich werden diese Behauptungen niemals mit einer Erklärung belegt.
Wo ich arbeite, scheint die zweite Version von den meisten anderen Entwicklern bevorzugt zu werden, und so tendiere ich auch zu diesem Stil, um Überraschungen zu minimieren. Aber in meinem Herzen denke ich wirklich an das Erste (da ich es ursprünglich so gelernt habe).
Ist eine dieser Formen objektiv besser als die andere? Wenn nicht, was wären die Gründe, eins übereinander zu verwenden?
sql
coding-style
SingleNegationElimination
quelle
quelle
Antworten:
Ich finde, dass die zweite Form besser ist. Das mag daran liegen, dass ich es so gelernt habe, ich gebe zu, aber ich habe einen konkreten Grund - die Trennung von Bedenken. Das Einfügen der Felder, die Sie zum Verknüpfen der Tabellen verwenden, in die where-Klausel kann zu Problemen beim Verständnis von Abfragen führen.
Nehmen Sie zum Beispiel die folgende Abfrage:
Die obige Abfrage enthält Tabellenverknüpfungsbedingungen und tatsächliche Geschäftslogikbedingungen, die alle in einem einzigen Bereich zusammengefasst sind. Bei einer großen Abfrage kann dies sehr schwer zu verstehen sein.
Nehmen Sie jedoch jetzt diesen Code:
In diesem Fall wird alles, was mit den Tabellen zu tun hat oder in welcher Beziehung sie zueinander stehen, von der from-Klausel isoliert, während sich die eigentliche Geschäftslogik für die Einschränkung von Abfragen in der where-Klausel befindet. Ich denke, das ist gerade bei größeren Anfragen viel verständlicher.
quelle
Die Join-Syntax hat 1992 die alte Komma-Syntax abgelöst. Derzeit gibt es keinen Grund, jemals Code mit der Komma-Syntax zu schreiben. Sie gewinnen nichts und haben einige Probleme, die Sie mit der expliziten Syntax einfach nicht haben.
Wenn Sie kompliziertere Abfragen erhalten, ist es in erster Linie sehr einfach, eine versehentliche Querverbindung durchzuführen, indem eine where-Bedingung fehlt. Dies kann durch die explizite Join-Syntax verhindert werden, da ein Syntaxfehler auftritt.
Wenn Sie einen Cross-Join beabsichtigen, wird dies durch die explizite Join-Syntax verdeutlicht, während in der impliziten Syntax angenommen wird, dass jemand, der die Wartung ausführt, vergessen hat, die where-Klausel hinzuzufügen.
Dann gibt es das Problem der Left- und Right-Joins, die zumindest in einigen DBs, die die implizite Syntax verwenden, problematisch sind. Sie sind in SQL Server veraltet und liefern tatsächlich keine korrekten Ergebnisse, auch nicht in den älteren Versionen. Keine Abfrage, die eine äußere Verknüpfung benötigt, sollte die implizite Syntax in SQL Server enthalten.
Außerdem habe ich hier und auf anderen Websites Fragen gesehen, bei denen beim Mischen der impliziten und expliziten Verknüpfungen (z. B. beim Hinzufügen einer linken Verknüpfung) falsche Ergebnisse aufgetreten sind. Daher ist es keine gute Idee, diese zu mischen.
Schließlich verstehen viele Leute, die implizite Verknüpfungen verwenden, Verknüpfungen nicht. Dies ist ein kritisches Verständnis, das Sie benötigen, um eine Datenbank effektiv abfragen zu können.
quelle
Ha. Ich habe gerade eine mögliche Antwort auf meine eigene Frage gefunden, als ich mir die Dokumentation für PostgreSQL angesehen habe . Um zusammenzufassen, was auf dieser Seite erklärt wird, ist die resultierende Abfrage immer noch dieselbe, aber die Anzahl der Pläne, die das Optimierungsprogramm berücksichtigen muss, wächst exponentiell mit der Anzahl der Joins.
Nach ungefähr sechs solchen Verknüpfungen ist die Anzahl so groß, dass die Zeit zum Planen der Abfrage möglicherweise spürbar ist. Nach ungefähr zehn wechselt das Optimierungsprogramm von einer umfassenden Suche nach Plänen zu einer probabilistischen Suche und gelangt möglicherweise nicht zum optimalen Plan .
Durch Festlegen eines Laufzeitparameters können Sie den Planer anweisen, explizit erwähnte Innen- und Kreuzverknüpfungen anders als implizite Verknüpfungen zu behandeln, sie an die oberste Stelle des Plans zu zwingen und andere Optionen nicht zu untersuchen.
Es ist zu beachten, dass das Standardverhalten in beiden Fällen dasselbe ist und dass das Abrufen alternativer Pläne das Wissen über die Interna der DBMS und die Besonderheiten der betreffenden Tabellen erfordert, um ein anderes Ergebnis zu erzielen
quelle
Nun, hier ist die Ansicht der Mengenlehre:
Wenn Sie zwei (oder mehr) Tabellennamen durch ein Komma trennen, ist das kartesische Produkt das, was Sie beabsichtigen. Jede Zeile der "linken" Tabelle wird mit der der rechten Tabelle "abgeglichen" (verkettet).
Wenn Sie nun etwas in die where-Klausel schreiben, ist das so, als würden Sie dieser Verkettung eine Bedingung hinzufügen, die angibt, welche Zeilen mit welchen Zeilen verkettet werden sollen.
Dies ist eigentlich das "Verbinden" der Zeilen :) und daher das Join-Schlüsselwort, das eine besser lesbare Syntax bietet und verständlicher ist, dass Sie "in der Tat" einige gemeinsame Werte verbinden möchten. Ähnlich wie @Dustin oben erklärt hat.
Jetzt ist jedes DBMS intelligent, dh es berechnet nicht erst das kartesische Produkt und filtert dann die Daten heraus (extrem verschwenderisch), sondern basiert auf der Abfragestruktur. Das Einzige, woran ich denken kann, ist, wenn Sie ihn bitten, beizutreten, ist es, als ob Sie die Beitrittsaktivität explizit machen und wahrscheinlich dabei helfen, den Code schneller auszuführen (um wie viel? Sie müssen ihn profilieren und sehen), aber in der In einem durch Kommas getrennten Fall braucht es einige Zeit, um die optimale Strategie zu finden. Ich kann mich irren, aber ich mache nur eine fundierte Vermutung, wie man es codieren würde ...
quelle
Ich denke, es ist im Allgemeinen besser, JOIN-Anweisungen für diesen Fall zu verwenden.
Wenn in Zukunft eine Situation auftritt, in der die Anweisung von INNER JOIN in OUTER JOIN geändert werden muss, ist dies mit der zweiten Anweisung viel einfacher.
quelle
Jedes RDBMS wird sie in Bezug auf die Ausführung gleich machen. Es kommt darauf an, ob man lesbarer und ausdrucksvoller ist.
Verwenden Sie JOIN, damit klar ist, was Join-Matching ist und was Auswahl ist, wie in:
gegen
Letzterer Fall macht sofort klar, welche Join-Bedingung und welches Auswahlkriterium vorliegt.
quelle
Ich habe die beiden Ergebnisse nur einmal in einer anderen Optimierungsreihe gesehen, und wenn der Speicher belegt ist, war dies in ms-sql2k bei einer wirklich haarigen Abfrage. In diesem einen Beispiel führte die alte Form, die mit * = verwendet wurde, zu einer etwa viermal schnelleren Leistung. Niemand, einschließlich unserer Microsoft-Techniker, konnte jemals erklären, warum. Die MS-Leute bezeichneten es als Fehler. Ich habe es nie wieder gesehen.
Da die meisten RDBMS klug genug sind, nicht die vollen Kartesier zu machen, ist der größte Grund, warum ich daran denken kann, sie nicht zu verwenden (abgesehen davon, dass sie abgeschrieben wird), dass die meisten Leute unter 30-35, mit denen ich gearbeitet habe, die noch nie gesehen haben alte Form vor und gehen schrecklich verloren, wenn sie darauf stoßen.
quelle
Der alte Stil ist veraltet, Sie sollten ihn nicht verwenden.
Es sollte nicht einmal einen Streit geben, über den man besser ist oder nicht. Neuer Code sollte nicht die alte Syntax verwenden.
quelle
Ein Grund für die prägnantere Syntax ist, dass sie prägnanter ist. Wenn Sie sich also damit auskennen, ist sie leichter zu lesen. Ich betrachte den ausführlichen Fall als vergleichbar mit dem Ausschreiben von Arithmetik in COBOL, z. B. MULTIPLY A BY B GIVING C.
quelle