In jedem Unternehmen, in dem ich gearbeitet habe, habe ich festgestellt, dass die Benutzer ihre SQL-Abfragen immer noch im ANSI-89-Standard schreiben:
select a.id, b.id, b.address_1
from person a, address b
where a.id = b.id
anstelle des ANSI-92-Standards:
select a.id, b.id, b.address_1
from person a
inner join address b
on a.id = b.id
Bei einer extrem einfachen Abfrage wie dieser gibt es keinen großen Unterschied in der Lesbarkeit. Bei großen Abfragen ist es jedoch viel einfacher zu erkennen, wo ich möglicherweise Probleme mit meiner Verknüpfung habe, wenn meine Verknüpfungskriterien mit der Auflistung der Tabelle gruppiert werden Lassen Sie mich alle meine Filter in meiner WHERE-Klausel behalten. Ganz zu schweigen davon, dass ich der Meinung bin, dass äußere Verknüpfungen viel intuitiver sind als die (+) - Syntax in Oracle.
Gibt es konkrete Leistungsvorteile bei der Verwendung von ANSI-92 gegenüber ANSI-89, wenn ich versuche, ANSI-92 an Menschen weiterzugeben? Ich würde es alleine versuchen, aber die Oracle-Setups, die wir hier haben, erlauben uns nicht, EXPLAIN PLAN zu verwenden - möchten nicht, dass die Leute versuchen, ihren Code zu optimieren, oder?
Antworten:
Laut "SQL Performance Tuning" von Peter Gulutzan und Trudy Pelzer gab es bei den sechs oder acht getesteten RDBMS-Marken keinen Unterschied in der Optimierung oder Leistung von SQL-89-Joins im Vergleich zu SQL-92-Joins. Man kann davon ausgehen, dass die meisten RDBMS-Engines die Syntax vor dem Optimieren oder Ausführen der Abfrage in eine interne Darstellung umwandeln, sodass die für Menschen lesbare Syntax keinen Unterschied macht.
Ich versuche auch, die SQL-92-Syntax zu evangelisieren. Sechzehn Jahre nach der Genehmigung ist es an der Zeit, dass die Leute damit beginnen! Alle Marken von SQL-Datenbanken unterstützen dies jetzt. Es gibt also keinen Grund, weiterhin die nicht standardmäßige
(+)
Oracle-Syntax oder die*=
Microsoft / Sybase-Syntax zu verwenden.Was den Grund angeht, warum es so schwierig ist, die Entwicklergemeinschaft der SQL-89-Gewohnheit zu brechen, kann ich nur davon ausgehen, dass es eine große "Basis der Pyramide" von Programmierern gibt, die per Copy & Paste anhand alter Beispiele aus Büchern, Zeitschriftenartikeln und anderen Codes codieren. oder eine andere Codebasis, und diese Leute lernen abstrakt keine neue Syntax. Einige Leute stimmen mit Mustern überein, andere lernen auswendig.
Ich sehe jedoch allmählich Leute, die häufiger SQL-92-Syntax verwenden als früher. Ich beantworte SQL-Fragen seit 1994 online.
quelle
Nun, der ANSI092-Standard enthält eine ziemlich abscheuliche Syntax. Natürliche Verknüpfungen sind eine und die USING-Klausel eine andere. IMHO sollte das Hinzufügen einer Spalte zu einer Tabelle den Code nicht beschädigen, aber ein NATURAL JOIN wird auf äußerst ungeheure Weise unterbrochen. Der "beste" Weg, um zu brechen, ist ein Kompilierungsfehler. Wenn Sie beispielsweise irgendwo SELECT * auswählen, kann eine Spalte hinzugefügt werdennicht kompilieren. Der nächstbeste Fehler wäre ein Laufzeitfehler. Es ist schlimmer, weil Ihre Benutzer es vielleicht sehen, aber es gibt Ihnen trotzdem eine nette Warnung, dass Sie etwas kaputt gemacht haben. Wenn Sie ANSI92 verwenden und Abfragen mit NATURAL-Joins schreiben, wird diese zur Kompilierungszeit nicht und zur Laufzeit nicht unterbrochen. Die Abfrage führt plötzlich zu falschen Ergebnissen. Diese Arten von Fehlern sind heimtückisch. Berichte gehen schief, möglicherweise sind finanzielle Angaben falsch.
Für diejenigen, die mit NATURAL Joins nicht vertraut sind. Sie verbinden zwei Tabellen mit jedem Spaltennamen, der in beiden Tabellen vorhanden ist. Was wirklich cool ist, wenn Sie einen 4-Spalten-Schlüssel haben und es satt haben, ihn zu tippen. Das Problem tritt auf, wenn Tabelle1 eine bereits vorhandene Spalte mit dem Namen BESCHREIBUNG enthält und Sie Tabelle2 eine neue Spalte mit dem Namen "Oh, ich weiß nicht" hinzufügen, die harmlos ist wie "mmm" BESCHREIBUNG. Jetzt verbinden Sie die beiden Tabellen auf einem VARCHAR2 (1000) Feld, das freie Form ist.
Die USING-Klausel kann zusätzlich zu dem oben beschriebenen Problem zu völliger Mehrdeutigkeit führen. In einem anderen SO-Beitrag zeigte jemand dieses ANSI-92-SQL und bat um Hilfe beim Lesen.
Dies ist völlig mehrdeutig. Ich habe eine UserID-Spalte sowohl in Unternehmen als auch in Benutzertabellen eingefügt, und es gibt keine Beschwerde. Was ist, wenn die UserID-Spalte in Unternehmen die ID der letzten Person ist, die diese Zeile geändert hat?
Ich meine es ernst. Kann jemand erklären, warum solche Unklarheiten notwendig waren? Warum ist es direkt in den Standard eingebaut?
Ich denke, Bill hat Recht, dass es eine große Basis von Entwicklern gibt, die dort durch Codierung kopieren / einfügen. Tatsächlich kann ich zugeben, dass ich in Bezug auf ANSI-92 eine Art bin. Jedes Beispiel, das ich jemals gesehen habe, zeigte mehrere Verknüpfungen, die in Klammern verschachtelt waren. Ehrlichkeit, das macht es bestenfalls schwierig, die Tische im SQL auszuwählen. Aber dann erklärte ein SQL92-Evangilist, dass dies tatsächlich eine Join-Reihenfolge erzwingen würde. JESUS ... all diese Copy-Paster, die ich gesehen habe, erzwingen jetzt tatsächlich eine Join-Reihenfolge - ein Job, der in 95% der Fälle besser Optimierern überlassen bleibt, insbesondere einem Copy / Paster.
Tomalak hat es richtig gemacht, als er sagte:
Es muss mir etwas geben und ich sehe keinen Vorteil. Und wenn es einen Vorteil gibt, sind die Negative ein Albatros, der zu groß ist, um ignoriert zu werden.
quelle
SELECT *
(dann herauszufinden, der Kunde verlässt sich auf Feldreihenfolge) - Es fühlt sich nur ein wenig schlampig anEinige Gründe fallen mir ein:
Ich für meinen Teil mache alle meine Joins in der SQL-92-Syntax und konvertiere Code, wo ich kann. Es ist die sauberere, lesbarere und leistungsfähigere Methode, dies zu tun. Es ist jedoch schwierig, jemanden davon zu überzeugen, den neuen Stil zu verwenden, wenn er der Meinung ist, dass er dadurch mehr Schreibarbeit leistet, ohne das Abfrageergebnis zu ändern.
quelle
Als Antwort auf den Beitrag NATURAL JOIN und USING oben.
WARUM würden Sie jemals die Notwendigkeit sehen, diese zu verwenden? Sie waren in ANSI-89 nicht verfügbar und wurden für ANSI-92 als eine Verknüpfung hinzugefügt, die ich nur sehen kann.
Ich würde einen Join niemals dem Zufall überlassen und immer die Tabelle / den Alias und die ID angeben.
Für mich ist der einzige Weg ANSI-92. Es ist ausführlicher und die Syntax wird von ANSI-89-Followern nicht gemocht, aber es trennt Ihre JOINS sauber von Ihrem FILTERING.
quelle
Lassen Sie mich zunächst sagen, dass in SQL Server die äußere Join-Syntax (* =) nicht immer korrekte Ergebnisse liefert. Es gibt Zeiten, in denen dies als Cross-Join und nicht als Outer-Join interpretiert wird. Es gibt also einen guten Grund, die Verwendung einzustellen. Und diese äußere Join-Syntax ist eine veraltete Funktion und wird in der nächsten Version von SQL Server nach SQL Server 2008 nicht mehr verfügbar sein. Sie können die inneren Joins weiterhin ausführen, aber warum sollte das überhaupt jemand wollen? Sie sind unklar und viel schwieriger zu pflegen. Sie wissen nicht leicht, was Teil des Joins ist und was eigentlich nur die where-Klausel ist.
Ein Grund, warum ich glaube, dass Sie die alte Syntax nicht verwenden sollten, ist, dass das Verstehen von Verknüpfungen und was sie tun und was nicht, ein kritischer Schritt für jeden ist, der SQL-Code schreibt. Sie sollten keinen SQL-Code schreiben, ohne die Verknüpfungen gründlich zu verstehen. Wenn Sie sie gut verstehen, werden Sie wahrscheinlich zu dem Schluss kommen, dass die ANSI-92-Syntax klarer und einfacher zu warten ist. Ich habe noch nie einen SQL-Experten getroffen, der die ANSI-92-Syntax nicht der alten Syntax vorgezogen hat.
Die meisten Leute, die ich getroffen habe oder mit denen ich mich befasst habe und die den alten Code verwenden, verstehen Joins wirklich nicht und geraten daher beim Abfragen der Datenbank in Schwierigkeiten. Dies ist meine persönliche Erfahrung, daher sage ich nicht, dass es immer wahr ist. Aber als Datenspezialist musste ich im Laufe der Jahre zu viel von diesem Müll reparieren, um es nicht zu glauben.
quelle
In der Schule wurde mir ANSI-89 beigebracht und ich arbeitete einige Jahre in der Industrie. Dann habe ich 8 Jahre lang die fabelhafte Welt von DBMS verlassen. Aber dann kam ich zurück und dieses neue ANSI 92-Zeug wurde unterrichtet. Ich habe die Join On-Syntax gelernt und unterrichte jetzt tatsächlich SQL. Ich empfehle die neue JOIN ON-Syntax.
Der Nachteil, den ich sehe, sind korrelierte Unterabfragen, die angesichts der ANSI 92-Verknüpfungen keinen Sinn ergeben. Wenn Join-Informationen im WHERE enthalten waren und korrelierte Unterabfragen im WHERE "verknüpft" wurden, schienen alle richtig und konsistent zu sein. In ANSI 92 befindet sich das Tabellenverknüpfungskriterium nicht in WHERE und die Unterabfrage "join" ist inkonsistent. Die Syntax scheint inkonsistent zu sein. Auf der anderen Seite würde der Versuch, diese Inkonsistenz zu "beheben", sie wahrscheinlich nur noch schlimmer machen.
quelle
Ich weiß die Antwort nicht genau. Dies ist ein religiöser Krieg (Albiet in geringerem Maße als Mac-Pc oder andere).
Eine Vermutung ist, dass Oracle (und möglicherweise auch andere Anbieter) bis vor kurzem den ANSI-92-Standard (ich glaube, er war in Oracle v9 oder so ungefähr) nicht übernommen hat, und dies auch für DBAs / Db-Entwickler, die in Unternehmen arbeiten, die verwendeten immer noch diese Versionen (oder wollten, dass Code auf Servern portierbar ist, die diese Versionen verwenden könnten, mussten sie sich an den alten Standard halten ...
Es ist wirklich eine Schande, denn die neue Join-Syntax ist viel besser lesbar und die alte Syntax erzeugt in mehreren gut dokumentierten Szenarien falsche (falsche) Ergebnisse.
quelle
INNER JOIN
wurde 1995 hinzugefügt ,LEFT JOIN
jedoch erst 1996. MySQL unterstützt es mindestens seit 3.23, das 1999 veröffentlicht wurde. PostgreSQL mindestens seit 7.2, veröffentlicht im Jahr 2002. Einige gelegentliche Googeln gibt mir keine Antwort für Teradata.Trägheit und Praktikabilität.
ANSI-92 SQL ist wie Tippen. In gewisser theoretischer Hinsicht könnte es eines Tages alles besser machen, aber ich kann jetzt viel schneller tippen, wenn ich mit vier Fingern auf die Tasten schaue. Ich müsste rückwärts gehen, um vorwärts zu gehen, ohne die Garantie, dass es jemals eine Auszahlung geben würde.
Das Schreiben von SQL macht ungefähr 10% meiner Arbeit aus. Wenn ich ANSI-92 SQL benötige, um ein Problem zu lösen, das ANSI-89 SQL nicht lösen kann, verwende ich es. (Ich verwende es tatsächlich in Access.) Wenn es mir helfen würde, meine bestehenden Probleme viel schneller zu lösen, würde ich mir die Zeit nehmen, es zu assimilieren. Aber ich kann ANSI-89 SQL auspeitschen, ohne jemals über die Syntax nachzudenken. Ich werde dafür bezahlt, Probleme zu lösen - das Nachdenken über die SQL-Syntax ist eine Verschwendung meiner Zeit und des Geldes meines Arbeitgebers.
Eines Tages, junger Grasshopper, werden Sie Ihre Verwendung der ANSI-92-SQL-Syntax gegen junge Leute verteidigen, die jammern, dass Sie SQL3 (oder was auch immer) verwenden sollten. Und dann wirst du verstehen. :-)
quelle
Ich hatte eine Abfrage, die ursprünglich für SQL Server 6.5 geschrieben wurde und die SQL 92-Join-Syntax nicht unterstützte, d. H.
wurde stattdessen geschrieben als
Die Abfrage gab es schon eine Weile, und die relevanten Daten hatten sich angesammelt, um die Abfrage zu langsam laufen zu lassen, etwa 90 Sekunden, um sie abzuschließen. Zu dem Zeitpunkt, als dieses Problem auftrat, hatten wir ein Upgrade auf SQL Server 7 durchgeführt.
Nachdem ich mich mit Indizes und anderen Ostern beschäftigt hatte, änderte ich die Join-Syntax so, dass sie SQL 92-kompatibel war. Die Abfragezeit fiel auf 3 Sekunden.
Es gibt einen guten Grund zu wechseln.
Von hier aus neu gepostet .
quelle
Ich kann aus der Sicht eines durchschnittlichen Entwicklers antworten, der gerade genug SQL kennt, um beide Syntaxen zu verstehen, aber trotzdem jedes Mal, wenn ich es brauche, die genaue Syntax des Einfügens googelt ... :-P (Ich mache nicht den ganzen Tag SQL , nur einige Probleme von Zeit zu Zeit zu beheben.)
Nun, eigentlich finde ich die erste Form intuitiver und mache keine offensichtliche Hierarchie zwischen den beiden Tabellen. Die Tatsache, dass ich SQL mit möglicherweise alten Büchern gelernt habe und das erste Formular zeige, hilft wahrscheinlich nicht ... ;-)
Und die erste Referenz, die ich bei einer SQL-Auswahlsuche in Google finde (die für mich hauptsächlich französische Antworten zurückgibt ... ) zeigt zuerst die ältere Form (dann erkläre die zweite).
Nur ein paar Hinweise zur "Warum" -Frage geben ... ^ _ ^ Ich sollte ein gutes, modernes Buch (DB-Agnostiker) zu diesem Thema lesen. Wenn jemand Vorschläge hat ...
quelle
Ich kann nicht für alle Schulen sprechen, aber an unserer Universität, als wir das SQL-Modul unseres Kurses absolvierten, unterrichteten sie nicht ANSI-92, sondern ANSI-89 - auf einem alten VAX-System! Ich war ANSI-92 erst ausgesetzt, als ich anfing, in Access herumzuwühlen, nachdem ich einige Abfragen mit dem Abfrage-Designer erstellt und dann in den SQL-Code eingegraben hatte. Als ich merkte, dass ich keine Ahnung hatte, wie die Verknüpfungen abgeschlossen wurden oder welche Auswirkungen die Syntax hatte, begann ich tiefer zu graben, damit ich sie verstehen konnte.
Angesichts der Tatsache, dass die verfügbare Dokumentation in vielen Fällen nicht gerade intuitiv ist und die Menschen dazu neigen, sich an das zu halten, was sie wissen, und in vielen Fällen nicht danach streben, mehr zu lernen, als sie benötigen, um ihre Arbeit zu erledigen, ist dies der Fall leicht zu erkennen, warum die Adoption so lange dauert.
Natürlich gibt es jene technischen Evangelisten, die gerne basteln und verstehen, und es sind eher jene Typen, die die "neueren" Prinzipien übernehmen und versuchen, den Rest zu konvertieren.
Seltsamerweise scheinen mir viele Programmierer die Schule zu verlassen und aufhören, sich weiterzuentwickeln. Ich denke, weil es das ist, was ihnen beigebracht wurde, wird es so gemacht. Erst wenn Sie Ihre Blinker abnehmen, erkennen Sie, dass die Schule nur dazu gedacht war, Ihnen die Grundlagen beizubringen und Ihnen genug Verständnis zu vermitteln, um den Rest selbst zu lernen, und dass Sie wirklich kaum an der Oberfläche des Wissens kratzten. Jetzt ist es Ihre Aufgabe, diesen Weg fortzusetzen.
Das ist natürlich nur meine Meinung, basierend auf meiner Erfahrung.
quelle
1) Standardmethode zum Schreiben von OUTER JOIN gegenüber * = oder (+) =
2) NATÜRLICHE VERBINDUNG
3) Abhängig von der Datenbank-Engine sind ANSI-92-Trends optimaler.
4) Manuelle Optimierung:
Nehmen wir an, wir haben die nächste Syntax (ANSI-89):
Es könnte geschrieben werden als:
Aber auch als:
Alle (1), (2), (3) geben das gleiche Ergebnis zurück, jedoch sind sie unterschiedlich optimiert. Dies hängt von der Datenbank-Engine ab, aber die meisten von ihnen tun dies:
5) Längere Abfragen sind weniger chaotisch.
quelle
Gründe, warum Menschen ANSI-89 aus meiner praktischen Erfahrung mit alten und jungen Programmierern, Auszubildenden und neuen Absolventen verwenden:
Ich persönlich bevorzuge ANSI-92 und ändere jede Abfrage, die ich in der ANSI-89-Syntax sehe, manchmal nur, um die vorliegende SQL-Anweisung besser zu verstehen. Ich stellte jedoch fest, dass die meisten Leute, mit denen ich zusammenarbeite, nicht in der Lage sind, Verknüpfungen über viele Tabellen zu schreiben. Sie codieren so gut sie können und verwenden das, was sie sich beim ersten Auftreten einer SQL-Anweisung gemerkt haben.
quelle
Hier sind einige Punkte, die SQL-89 und SQL-92 vergleichen und einige Missverständnisse in anderen Antworten beseitigen.
NATURAL JOINS
sind eine schreckliche Idee. Sie sind implizit und erfordern Metainformationen über die Tabelle. Nichts an SQL-92 erfordert ihre Verwendung. Ignorieren Sie sie einfach . Sie sind für diese Diskussion nicht relevant.USING
ist eine großartige Idee, sie hat zwei Auswirkungen:id
in beide Tabellen geschrieben. Nachdem Sie die Tabellen verknüpft haben, wird dies mehrdeutig und erfordert explizites Aliasing. Außerdem hatten dieid
s auf dem Join mit ziemlicher Sicherheit unterschiedliche Daten. Wenn Sie Person Unternehmen einzusteigen, haben Sie jetzt zu alias einenid
zuperson_id
, und manid
zucompany_id
, ohne die die beitreten würden zwei mehrdeutige Spalten erzeugen. Die Verwendung einer global eindeutigen Kennung für den Ersatzschlüssel der Tabelle ist die Konvention, mit der der Standard belohntUSING
.CROSS JOIN
. ACROSS JOIN
reduziert den Satz nicht, sondern vergrößert ihn implizit.FROM T1,T2
ist das gleiche wieFROM T1 CROSS JOIN T2
, das einen kartesischen Join erzeugt, der normalerweise nicht das ist, was Sie wollen. Wenn Sie die Selektivität haben, diese auf eine entfernteWHERE
Bedingung zu reduzieren, ist es wahrscheinlicher, dass Sie beim Entwurf Fehler machen.,
Explizite SQL-89- und SQL-92-JOIN
S haben unterschiedliche Priorität.JOIN
hat eine höhere Priorität. Schlimmer noch, einige Datenbanken wie MySQL haben dies sehr lange falsch verstanden. . Das Mischen der beiden Stile ist daher eine schlechte Idee, und der heute weitaus populärere Stil ist der SQL-92-Stil.quelle
Oracle implementiert ANSI-92 überhaupt nicht gut. Ich hatte mehrere Probleme, nicht zuletzt, weil die Datentabellen in Oracle Apps so gut mit Spalten ausgestattet sind. Wenn die Anzahl der Spalten in Ihren Joins etwa 1050 Spalten überschreitet (was in Apps sehr einfach ist), wird dieser falsche Fehler angezeigt, der absolut keinen logischen Sinn ergibt:
Wenn Sie die Abfrage neu schreiben, um die Join-Syntax im alten Stil zu verwenden, verschwindet das Problem, was den Schuldigen eindeutig auf die Implementierung von ANSI-92-Joins zu deuten scheint.
Bis ich auf dieses Problem stieß, war ich ein unerschütterlicher Förderer von ASNI-92, da die Wahrscheinlichkeit einer versehentlichen Kreuzverknüpfung geringer ist, was mit der Syntax alten Stils viel zu einfach ist.
Jetzt fällt es mir jedoch viel schwerer, darauf zu bestehen. Sie weisen auf die schlechte Implementierung von Oracle hin und sagen: "Wir machen es auf unsere Weise, danke."
quelle
Ein neuer SQL-Standard erbt alles vom vorherigen Standard, auch bekannt als "die Fesseln der Kompatibilität". Der 'alte' / 'durch Kommas getrennte' / 'nicht qualifizierte' Join-Stil ist also eine vollkommen gültige SQL-92-Systemsteuer.
Jetzt behaupte ich, dass SQL-92
NATURAL JOIN
die einzige Verbindung ist, die Sie benötigen. Ich behaupte zum Beispiel, dass es überlegen ist,inner join
weil es keine doppelten Spalten generiert - keine Bereichsvariablen mehr inSELECT
Klauseln, um Spalten zu disambiguieren! Aber ich kann nicht erwarten, dass sich jedes Herz und jeder Verstand ändert, deshalb muss ich mit Codierern zusammenarbeiten, die weiterhin das übernehmen, was ich persönlich als Legacy-Join-Stile betrachte (und sie können sogar Bereichsvariablen als "Aliase" bezeichnen!). Dies liegt in der Natur der Teamarbeit und nicht im luftleeren Raum.Einer der Kritikpunkte an der SQL-Sprache ist, dass das gleiche Ergebnis mit einer Reihe von semantisch äquivalenten Syntaxen erzielt werden kann (einige mit relationaler Algebra, andere mit relationaler Berechnung), wobei die Auswahl der "besten" einfach auf den persönlichen Stil zurückzuführen ist . Ich fühle mich mit den 'alten' Verbindungen genauso wohl wie mit
INNER
. Ob ich mir die Zeit nehmen würde, sie neu zu schreiben,NATURAL
hängt vom Kontext ab.quelle