In Learn SQL the Hard Way (Übung 6) präsentiert der Autor die folgende Abfrage:
SELECT pet.id, pet.name, pet.age, pet.dead
FROM pet, person_pet, person
WHERE
pet.id = person_pet.pet_id AND
person_pet.person_id = person.id AND
person.first_name = "Zed";
und sagt dann weiter:
Es gibt tatsächlich andere Möglichkeiten, diese Art von Abfragen zum Funktionieren zu bringen, die als "Verknüpfungen" bezeichnet werden. Ich vermeide diese Konzepte vorerst, weil sie wahnsinnig verwirrend sind. Halten Sie sich fürs Erste an diese Art des Zusammenfügens von Tabellen und ignorieren Sie Leute, die versuchen, [Ihnen] zu sagen, dass dies irgendwie langsamer oder "niedriger" ist.
Ist das wahr? Warum oder warum nicht?
Antworten:
Mit dem Ansatz des Autors wird das Unterrichten von OUTER JOINs sehr viel schwieriger. Die ON-Klausel in INNER JOIN hat mich nie umgehauen wie viele andere Sachen. Vielleicht liegt es daran, dass ich nie den alten Weg gelernt habe. Ich würde gerne glauben, dass es einen Grund dafür gibt, warum wir es losgeworden sind, und es war nicht so einfach, diese Methode als low class zu bezeichnen.
Es ist wahr, in dem sehr engen Szenario, das der Autor erstellt hat:
Als Teil eines Lehrfortschritts denke ich, dass es einfacher ist, ihn zu zerlegen und einen natürlichen Fortschritt zu haben:
Die Konzepte zum Verknüpfen und Filtern von Tabellen sind nicht wirklich identisch. Die korrekte Syntax Lernen wird nun carry-over haben , wenn Sie OUTER lernen JOINS es sei denn , der Autor auf die Lehre veraltet / veraltet Dinge will wie:
*= or =*
.quelle
*=
oder=*
zeigte linke oder rechte äußere Verknüpfungen an, eine andere, die ich nur mit einem|=
Operator unterstützte.+=
oder vielleicht war es=+
. Ich glaube,*=
war Transact-SQL (Sybase und später MS-SQL). Trotzdem guter Punkt.WHERE
Klausel auszuführen. (Ich habe gehört, dass dies als Theta-Join bezeichnet wird, bin mir aber nicht sicher, ob das richtig ist.)Ob es langsamer ist, hängt vom Abfrageoptimierer ab und davon, wie es die Abfrage optimiert (was Sie schreiben, ist nicht das, was ausgeführt wird). Das große Problem bei diesem Zitat ist jedoch, dass die Tatsache, dass es verschiedene Arten von Joins gibt, die völlig unterschiedlich funktionieren, völlig ignoriert wird. Zum Beispiel ist das Gesagte (theoretisch) wahr
inner joins
, aber es gilt nicht fürouter joins
(left joins
undright joins
).quelle
INNER JOIN
oderLEFT OUTER JOIN
. Sie sind nicht "wahnsinnig verwirrend". SQL kann wahnsinnig verwirrend werden, aber dies ist kein Beispiel dafür.Der Autor stellt einen einfachen Fall vor, in dem entweder die alte oder die neue Syntax verwendet werden kann. Ich stimme seiner Aussage nicht zu, dass Verknüpfungen wahnsinnig verwirrend sind, da das Verknüpfen von Tabellen ein grundlegendes SQL-Abfragekonzept ist. Vielleicht sollte der Autor vorher einige Zeit damit verbracht haben, die Funktionsweise von JOINS zu erläutern, bevor er eine Stellungnahme abgibt und ein Beispiel für eine Abfrage mehrerer Tabellen ausführt.
Man sollte die neuere Syntax verwenden. Das Hauptargument dafür ist, dass Ihre Abfrage Folgendes haben wird:
Bei Verwendung des alten Stils werden die Join- und Filterkriterien kombiniert, was in komplexeren Fällen zu Verwirrung führen kann.
Sie können ein kartesisches Produkt auch erhalten, indem Sie ein Verknüpfungskriterium in der Filterklausel vergessen:
mit der älteren Syntax.
Die Verwendung der neueren Syntax gibt auch an, wie der Join erfolgen soll. Dies ist wichtig, wenn Sie ein INNER, LEFT OUTER usw. verwenden möchten. In Bezug auf die JOIN-Syntax ist es daher eindeutiger, dass IMHO die Lesbarkeit für diejenigen erhöht, die mit dem Verknüpfen von Tabellen nicht vertraut sind.
quelle
Es sollte keine geben, der Abfrageparser sollte eine äquivalente interne Darstellung für äquivalente Abfragen generieren, unabhängig davon, wie sie geschrieben wurden. Der Autor verwendet nur die Pre-SQL-92-Syntax, weshalb er erwähnt, dass sie möglicherweise als "altmodisch" oder "niedrig" eingestuft wird. Intern sollten der Parser und der Optimierer denselben Abfrageplan generieren.
quelle
Auf diese Weise habe ich SQL gelernt, einschließlich der
*=
Syntax für äußere Verknüpfungen. Für mich war es sehr intuitiv, da alle Beziehungen den gleichen Vorrang hatten und Abfragen besser als eine Reihe von Fragen aufstellten: Was möchten Sie? Woher willst du sie? Welche möchtest du?Durch die
join
Syntax wird der Denkprozess gegenüber den Beziehungen stärker gestört. Und persönlich finde ich den Code weitaus weniger lesbar, da die Tabellen und Beziehungen vermischt sind.Zumindest in MSSQL gibt es keinen signifikanten Unterschied in der Leistung der Abfragen, vorausgesetzt, Sie verwenden dieselbe Verknüpfungsreihenfolge. Das heißt, es gibt ein klares, großes Problem beim Erlernen (und Verwenden) von SQL auf diese Weise. Wenn Sie eine Ihrer Beziehungen vergessen, erhalten Sie unerwartete Cross-Produkte. Was in einer Datenbank von beliebiger Größe unerschwinglich teuer ist (und für Nichtauserwählte gefährlich ist!). Es ist viel schwieriger, eine Beziehung zu vergessen, wenn Sie die
join
Stilsyntax verwenden.quelle
Hierbei sind zwei verschiedene Aspekte zu berücksichtigen: Leistung und Wartbarkeit / Lesbarkeit .
Wartbarkeit / Lesbarkeit
Ich habe eine andere Abfrage ausgewählt, da dies meines Erachtens ein besseres / schlechteres Beispiel ist als die ursprüngliche Abfrage, die Sie veröffentlicht haben.
Was sieht für Sie besser aus und ist besser lesbar?
Oder...
Für mich persönlich ist der erste sehr gut lesbar. Sie sehen, dass wir Tabellen mit verknüpfen
INNER JOIN
, was bedeutet, dass wir die Zeilen abrufen, die mit der nachfolgenden Verknüpfungsklausel übereinstimmen (dh "Mitarbeiter mit EmployeeDepartmentHistory auf BusinessEntityID verknüpfen und diese Zeilen einschließen").Letzteres bedeutet mir das Komma nichts. Ich frage mich, was Sie mit all diesen
WHERE
Klauselprädikaten machen.Ersteres liest sich eher so, wie mein Gehirn denkt. Ich sehe mir jeden Tag den ganzen Tag SQL an und die Kommas für Joins. Was mich zu meinem nächsten Punkt führt ...
Sie sind alle miteinander verbunden. Sogar das Komma ist ein Join. Die Tatsache, dass der Autor sie nicht nennt, ist in der Tat ihr Untergang ... es ist nicht offensichtlich. Es sollte offensichtlich sein. Sie verbinden relationale Daten, unabhängig davon, ob Sie dies angeben
JOIN
oder,
.Performance
Dies wird definitiv RDBMS-abhängig sein. Ich kann nur im Auftrag von Microsoft SQL Server sprechen. In Bezug auf die Leistung sind diese gleichwertig. Woher weißt du das? Erfassen Sie die Post-Execution-Pläne und sehen Sie, was genau SQL Server für jede dieser Anweisungen tut:
Im obigen Bild habe ich hervorgehoben, dass ich beide Abfragen wie oben verwende und mich nur in den expliziten Zeichen für den Join unterscheide (
JOIN
vs,
) unterscheide. SQL Server macht genau dasselbe.Zusammenfassung
Verwenden Sie keine Kommas. Verwenden Sie explizite
JOIN
Anweisungen.quelle
Nein, das stimmt überhaupt nicht. Der Autor bereitet seine Leser auf Verwirrung vor und ermutigt zur Cargo-Kult-Programmierung, die einen sehr starken strukturellen Unterschied zwischen der Standardsyntax und dieser älteren Variante, die er bevorzugt, vermeidet. Insbesondere macht es eine überfüllte WHERE-Klausel schwieriger, herauszufinden, was seine Abfrage besonders macht.
Sein Beispiel veranlasst einen Leser, eine mentale Karte seiner Bedeutung zu generieren, die eine Menge Unordnung aufweist.
Grob gesagt ist das obige:
Mit einer solchen mentalen Karte kann der Leser (der aus irgendeinem Grund die SQL von Hand schreibt) sehr leicht einen Fehler machen, möglicherweise indem er eine oder mehrere Tabellen weglässt. Und ein Leser von Code, der so geschrieben ist, muss härter arbeiten, um genau herauszufinden, was der SQL-Autor versucht. ("Harder" ist auf der Ebene des Lesens von SQL mit oder ohne Syntaxhervorhebung, aber es ist immer noch ein Unterschied von mehr als Null.)
Es gibt einen Grund, warum JOINs üblich sind, und es ist der alte Klassiker unter den Canards, bei denen es um die Trennung von Interessen geht. Insbesondere für eine SQL-Abfrage gibt es einen guten Grund, die Struktur der Daten von der Filterung der Daten zu unterscheiden.
Wenn die Abfrage sauberer geschrieben ist, wie z
Dann hat der Leser eine klarere Unterscheidung zwischen den Komponenten dessen, was gefragt wird. Der Unterscheidungsfilter dieser Abfrage ist von der Beziehung seiner Komponenten zueinander getrennt, und die erforderlichen Komponenten jeder Beziehung befinden sich direkt neben dem Ort, an dem sie benötigt werden.
Natürlich sollte ein modernes Datenbanksystem keinen signifikanten Unterschied zwischen den beiden Stilen erkennen. Wenn jedoch die Datenbankleistung die einzige Überlegung wäre, würde die SQL-Abfrage auch keinen Leerraum oder keine Großschreibung aufweisen.
quelle
Guy macht einen klassischen Fehler. Er versucht, ein abstraktes Konzept mit einer bestimmten Implementierung zu vermitteln. Sobald Sie das tun, geraten Sie in dieses Chaos.
Sollte zuerst grundlegende Datenbankkonzepte vermittelt haben, dann sollte SQL als eine Möglichkeit zur Beschreibung dieser Konzepte gezeigt werden.
Links und rechts verbinden sich, man könnte behaupten, dass sie nicht allzu wichtig sind. Outer Join, nun, Sie könnten die alte
*=
und=*
Syntax verwenden.Nun könnte man argumentieren, dass die Syntax einfacher ist, aber nur für einfache Abfragen. Sobald Sie versuchen, mit dieser Version eine komplexe Abfrage durchzuführen, können Sie in ein schreckliches Chaos geraten. Die "neue" Syntax wurde nicht eingeführt, damit Sie komplexe Abfragen ausführen können. Sie haben komplexe Abfragen auf lesbare und daher wartbare Weise ausgeführt.
quelle
Das Beispiel entspricht der einfachen Neuformulierung mit inneren JOINs. Der Unterschied liegt allein in den zusätzlichen Möglichkeiten, die die JOIN-Syntax bietet. Sie können beispielsweise die Reihenfolge angeben, in der die Spalten der beiden beteiligten Tabellen verarbeitet werden. Siehe z . B. https://stackoverflow.com/a/1018825/259310 .
Die empfangene Weisheit besteht darin, Ihre Anfragen im Zweifelsfall so zu schreiben, dass sie besser lesbar sind. Ob JOIN- oder WHERE-Formulierungen jedoch leichter zu lesen sind, scheint eine Frage der persönlichen Präferenz zu sein, weshalb beide Formen so verbreitet sind.
quelle
WHERE
die Klausel verwenden oder in dieJOIN
Anweisung einfügen, kann sich je nach Abfrageoptimierung tatsächlich auf die Leistung auswirken. Ich habe es mehr als einmal gesehen.Als ich SQL lernte, existierten die Formulare INNER JOIN, LEFT JOIN usw. nicht. Wie bereits in anderen Antworten erwähnt, wurden in verschiedenen SQL-Dialekten jeweils Outer-Joins mit eigenwilliger Syntax implementiert. Diese beschädigte Portabilität von SQL-Code. Das Zusammenführen der Sprache erforderte einige Änderungen, und LEFT JOIN usw. war das, worauf sie sich einließen.
Es ist wahr, dass für jeden INNER JOIN ein gleichwertiger Komma-Join mit der Join-Bedingung in der WHERE-Klausel geschrieben werden kann. Ich habe eine Weile gebraucht, um von der Vorliebe für die alte Form zur Vorliebe für die neue Form überzugehen. Offenbar hält der Autor von Learning SQL the Hard Way den alten Weg immer noch für einfacher.
Gibt es da unterschiede Na ja, das gibt es. Das erste ist, dass ein INNER JOIN mit einer ON-Klausel die Absicht des Autors klarer offenbart als der Join im alten Stil. Die Tatsache, dass die ON-Klausel tatsächlich eine Join-Bedingung und keine andere Einschränkung ist, ist offensichtlicher. Dadurch ist Code, der INNER JOIN verwendet, beim Lesen leichter zu erlernen als der alte Stil. Dies ist wichtig, wenn Sie den Code eines anderen Benutzers verwalten.
Der zweite Unterschied besteht darin, dass der neue Stil es dem Abfrageoptimierer geringfügig erleichtert, die Gewinnstrategie zu ermitteln. Dies ist ein sehr kleiner Effekt, aber er ist real.
Der dritte Unterschied besteht darin, dass beim Lernen mit INNER JOIN (oder einfach nur JOIN) das Erlernen von LEFT JOIN usw. erleichtert wird.
Abgesehen davon gibt es überhaupt keinen materiellen Unterschied.
quelle
Es kommt darauf an, ob Sie in Mengen und formaler Logik denken.
Wenn Sie das Schlüsselwort "join" nicht verwenden, wird der Übergang von der formalen Logik zu SQL vereinfacht.
Aber wenn Sie, wie 99% der Menschen, in Ihrem Mathematikstudium keinen Spaß an formaler Logik hatten, ist das Join-Schlüsselwort ein einfacherer Lerneffekt. Früher wurde SQL an der Universität präsentiert, um formale logische Abfragen niederzuschreiben.
quelle