INNER JOIN vs LEFT JOIN-Leistung in SQL Server

259

Ich habe einen SQL-Befehl erstellt, der INNER JOIN für 9 Tabellen verwendet. Dieser Befehl dauert jedoch sehr lange (mehr als fünf Minuten). Mein Volk schlug mir daher vor, INNER JOIN in LEFT JOIN zu ändern, da die Leistung von LEFT JOIN trotz meiner Kenntnisse besser ist. Nachdem ich es geändert hatte, wurde die Abfragegeschwindigkeit erheblich verbessert.

Ich würde gerne wissen, warum LEFT JOIN schneller ist als INNER JOIN?

Mein SQL-Befehl sieht wie folgt aus: SELECT * FROM A INNER JOIN B ON ... INNER JOIN C ON ... INNER JOIN Dund so weiter

Update: Dies ist eine kurze Beschreibung meines Schemas.

FROM sidisaleshdrmly a -- NOT HAVE PK AND FK
    INNER JOIN sidisalesdetmly b -- THIS TABLE ALSO HAVE NO PK AND FK
        ON a.CompanyCd = b.CompanyCd 
           AND a.SPRNo = b.SPRNo 
           AND a.SuffixNo = b.SuffixNo 
           AND a.dnno = b.dnno
    INNER JOIN exFSlipDet h -- PK = CompanyCd, FSlipNo, FSlipSuffix, FSlipLine
        ON a.CompanyCd = h.CompanyCd
           AND a.sprno = h.AcctSPRNo
    INNER JOIN exFSlipHdr c -- PK = CompanyCd, FSlipNo, FSlipSuffix
        ON c.CompanyCd = h.CompanyCd
           AND c.FSlipNo = h.FSlipNo 
           AND c.FSlipSuffix = h.FSlipSuffix 
    INNER JOIN coMappingExpParty d -- NO PK AND FK
        ON c.CompanyCd = d.CompanyCd
           AND c.CountryCd = d.CountryCd 
    INNER JOIN coProduct e -- PK = CompanyCd, ProductSalesCd
        ON b.CompanyCd = e.CompanyCd
           AND b.ProductSalesCd = e.ProductSalesCd 
    LEFT JOIN coUOM i -- PK = UOMId
        ON h.UOMId = i.UOMId 
    INNER JOIN coProductOldInformation j -- PK = CompanyCd, BFStatus, SpecCd
        ON a.CompanyCd = j.CompanyCd
            AND b.BFStatus = j.BFStatus
            AND b.ProductSalesCd = j.ProductSalesCd
    INNER JOIN coProductGroup1 g1 -- PK = CompanyCd, ProductCategoryCd, UsedDepartment, ProductGroup1Cd
        ON e.ProductGroup1Cd  = g1.ProductGroup1Cd
    INNER JOIN coProductGroup2 g2 -- PK = CompanyCd, ProductCategoryCd, UsedDepartment, ProductGroup2Cd
        ON e.ProductGroup1Cd  = g2.ProductGroup1Cd
Anonym
quelle
1
Projizieren Sie ein Attribut von coUOM? Wenn nicht, können Sie möglicherweise einen Semi-Join verwenden. Wenn ja, können Sie UNIONals Alternative verwenden. Nur Ihre FROMKlausel zu veröffentlichen, ist hier eine unzureichende Information.
Tag, wenn
1
Ich habe mich so oft gefragt (weil ich die ganze Zeit sehe).
Paul Draper
1
Haben Sie in Ihrem kurzen Schema eine Bestellung von verpasst? Ich hatte kürzlich ein Problem, bei dem das Ändern eines INNER JOIN in LEFT OUTER JOIN die Abfrage von 3 Minuten auf 10 Sekunden beschleunigt. Wenn Ihre Bestellung wirklich "Bestellen nach" enthält, werde ich dies als Antwort näher erläutern. Es sah so aus, als ob alle Antworten den Fall, mit dem ich konfrontiert war, nicht wirklich erklärten.
Phuah Yee Keat

Antworten:

403

A LEFT JOINist absolut nicht schneller als a INNER JOIN. In der Tat ist es langsamer; Per Definition muss ein Outer Join ( LEFT JOINoder RIGHT JOIN) die gesamte Arbeit eines INNER JOINPlus erledigen, zusätzlich die zusätzliche Arbeit, die Ergebnisse auf Null zu erweitern. Es wird auch erwartet, dass mehr Zeilen zurückgegeben werden, was die Gesamtausführungszeit allein aufgrund der größeren Größe der Ergebnismenge weiter erhöht.

(Und selbst wenn ein LEFT JOIN waren schneller in bestimmten Situationen aufgrund einiger schwer denken Zusammenfluß von Faktoren ist es nicht funktional äquivalent zu einem INNER JOIN, so dass Sie nicht einfach alle Instanzen eine mit dem anderen zu ersetzen gehen kann!)

Höchstwahrscheinlich liegen Ihre Leistungsprobleme an anderer Stelle, z. B. wenn ein Kandidatenschlüssel oder ein Fremdschlüssel nicht ordnungsgemäß indiziert ist. 9 Tische sind ziemlich viel zu verbinden, so dass die Verlangsamung buchstäblich fast überall sein könnte. Wenn Sie Ihr Schema veröffentlichen, können wir möglicherweise weitere Details bereitstellen.


Bearbeiten:

Wenn ich weiter darüber nachdenke, könnte ich mir einen Umstand vorstellen, unter dem a LEFT JOINschneller sein könnte als a INNER JOIN, und dann:

  • Einige der Tabellen sind sehr klein (z. B. unter 10 Zeilen).
  • Die Tabellen verfügen nicht über ausreichende Indizes, um die Abfrage abzudecken.

Betrachten Sie dieses Beispiel:

CREATE TABLE #Test1
(
    ID int NOT NULL PRIMARY KEY,
    Name varchar(50) NOT NULL
)
INSERT #Test1 (ID, Name) VALUES (1, 'One')
INSERT #Test1 (ID, Name) VALUES (2, 'Two')
INSERT #Test1 (ID, Name) VALUES (3, 'Three')
INSERT #Test1 (ID, Name) VALUES (4, 'Four')
INSERT #Test1 (ID, Name) VALUES (5, 'Five')

CREATE TABLE #Test2
(
    ID int NOT NULL PRIMARY KEY,
    Name varchar(50) NOT NULL
)
INSERT #Test2 (ID, Name) VALUES (1, 'One')
INSERT #Test2 (ID, Name) VALUES (2, 'Two')
INSERT #Test2 (ID, Name) VALUES (3, 'Three')
INSERT #Test2 (ID, Name) VALUES (4, 'Four')
INSERT #Test2 (ID, Name) VALUES (5, 'Five')

SELECT *
FROM #Test1 t1
INNER JOIN #Test2 t2
ON t2.Name = t1.Name

SELECT *
FROM #Test1 t1
LEFT JOIN #Test2 t2
ON t2.Name = t1.Name

DROP TABLE #Test1
DROP TABLE #Test2

Wenn Sie dies ausführen und den Ausführungsplan anzeigen, werden Sie feststellen, dass die INNER JOINAbfrage tatsächlich mehr kostet als die LEFT JOIN, da sie die beiden oben genannten Kriterien erfüllt. Dies liegt daran, dass SQL Server eine Hash-Übereinstimmung für die durchführen möchte INNER JOIN, jedoch verschachtelte Schleifen für die LEFT JOIN; Ersteres ist normalerweise viel schneller, aber da die Anzahl der Zeilen so gering ist und kein Index verwendet werden kann, stellt sich heraus, dass die Hashing-Operation der teuerste Teil der Abfrage ist.

Sie können den gleichen Effekt erzielen, indem Sie ein Programm in Ihrer bevorzugten Programmiersprache schreiben, um eine große Anzahl von Suchvorgängen in einer Liste mit 5 Elementen durchzuführen, im Vergleich zu einer Hash-Tabelle mit 5 Elementen. Aufgrund der Größe ist die Hash-Tabellenversion tatsächlich langsamer. Erhöhen Sie es jedoch auf 50 Elemente oder 5000 Elemente, und die Listenversion verlangsamt sich zu einem Crawl, da es für die Hashtabelle O (N) vs. O (1) ist.

Wenn Sie diese Abfrage jedoch so ändern, dass sie sich in der IDSpalte statt befindet Name, wird eine ganz andere Geschichte angezeigt. In diesem Fall werden verschachtelte Schleifen für beide Abfragen ausgeführt, aber die INNER JOINVersion kann einen der Clustered-Index-Scans durch eine Suche ersetzen. Dies bedeutet, dass dies bei einer großen Anzahl von Zeilen buchstäblich eine Größenordnung schneller ist.

Die Schlussfolgerung ist also mehr oder weniger das, was ich oben in mehreren Absätzen erwähnt habe. Dies ist mit ziemlicher Sicherheit ein Indexierungs- oder Indexabdeckungsproblem, möglicherweise kombiniert mit einer oder mehreren sehr kleinen Tabellen. Das sind die einzigen Umstände , unter denen SQL Server können manchmal einen schlechteren Ausführungsplan für einen wählen INNER JOINals ein LEFT JOIN.

Aaronaught
quelle
4
Es gibt ein anderes Szenario, das dazu führen kann, dass ein OUTER JOIN besser abschneidet als ein INNER JOIN. Siehe meine Antwort unten.
Dbenham
12
Ich möchte darauf hinweisen, dass es im Grunde keine Datenbankdokumentation gibt, die die Idee unterstützt, dass die Leistung von inneren und äußeren Verknüpfungen unterschiedlich ist. Äußere Verknüpfungen sind aufgrund des Datenvolumens und der Größe der Ergebnismenge etwas teurer als innere Verknüpfungen. Die zugrunde liegenden Algorithmen ( msdn.microsoft.com/en-us/library/ms191426(v=sql.105).aspx ) sind jedoch für beide Arten von Verknüpfungen gleich. Die Leistung sollte ähnlich sein, wenn sie ähnliche Datenmengen zurückgeben.
Gordon Linoff
3
@Aaronaught. . . Auf diese Antwort wurde in einem Kommentar verwiesen, der besagte, dass "äußere Verknüpfungen signifikant schlechter abschneiden als innere Verknüpfungen". Ich habe nur kommentiert, um sicherzugehen, dass sich diese Fehlinterpretation nicht verbreitet.
Gordon Linoff
16
Ich denke, diese Antwort ist in einem wichtigen Aspekt irreführend: Weil darin steht "Ein linker Beitritt ist absolut nicht schneller als ein innerer Beitritt". Diese Zeile ist nicht korrekt. Es ist theoretisch nicht schneller als ein INNER JOIN. Es ist NICHT "absolut nicht schneller". Die Frage ist speziell eine Leistungsfrage. In der Praxis habe ich jetzt einige Systeme gesehen (von sehr großen Unternehmen!), Bei denen INNER JOIN im Vergleich zu OUTER JOIN lächerlich langsam war. Theorie und Praxis sind sehr unterschiedliche Dinge.
David Frenkel
5
@ DavidFrenkel: Das ist höchst unwahrscheinlich. Ich würde um einen A / B-Vergleich mit Ausführungsplänen bitten, wenn Sie glauben, dass eine solche Diskrepanz möglich ist. Möglicherweise hängt es mit zwischengespeicherten Abfrage- / Ausführungsplänen oder fehlerhaften Statistiken zusammen.
Aaronaught
127

Es gibt ein wichtiges Szenario, das dazu führen kann, dass ein äußerer Join schneller ist als ein innerer Join, der noch nicht besprochen wurde.

Bei Verwendung eines äußeren Joins kann der Optimierer die äußere verknüpfte Tabelle immer aus dem Ausführungsplan löschen, wenn die Join-Spalten die PK der äußeren Tabelle sind und keine der äußeren Tabellenspalten außerhalb des äußeren Joins selbst referenziert wird. Beispiel: SELECT A.* FROM A LEFT OUTER JOIN B ON A.KEY=B.KEYB.KEY ist die PK für B. Sowohl Oracle (ich glaube, ich habe Release 10 verwendet) als auch SQL Server (ich habe 2008 R2 verwendet) bereinigen Tabelle B aus dem Ausführungsplan.

Dasselbe gilt nicht unbedingt für einen inneren Join: SELECT A.* FROM A INNER JOIN B ON A.KEY=B.KEYAbhängig von den vorhandenen Einschränkungen kann B im Ausführungsplan erforderlich sein oder nicht.

Wenn A.KEY ein nullbarer Fremdschlüssel ist, der auf B.KEY verweist, kann der Optimierer B nicht aus dem Plan entfernen, da er bestätigen muss, dass für jede A-Zeile eine B-Zeile vorhanden ist.

Wenn A.KEY ein obligatorischer Fremdschlüssel ist, der auf B.KEY verweist, kann der Optimierer B aus dem Plan entfernen, da die Einschränkungen die Existenz der Zeile garantieren. Nur weil der Optimierer die Tabelle aus dem Plan entfernen kann, heißt das nicht, dass dies der Fall ist. SQL Server 2008 R2 löscht B NICHT aus dem Plan. Oracle 10 löscht B aus dem Plan. In diesem Fall ist leicht zu erkennen, wie der äußere Join den inneren Join auf SQL Server übertrifft.

Dies ist ein triviales Beispiel und für eine eigenständige Abfrage nicht praktikabel. Warum an einen Tisch gehen, wenn Sie nicht müssen?

Dies könnte jedoch eine sehr wichtige Entwurfsüberlegung beim Entwerfen von Ansichten sein. Häufig wird eine "Alles-tun" -Ansicht erstellt, die alles zusammenfügt, was ein Benutzer möglicherweise in Bezug auf eine zentrale Tabelle benötigt. (Insbesondere, wenn naive Benutzer Ad-hoc-Abfragen ausführen, die das relationale Modell nicht verstehen.) Die Ansicht enthält möglicherweise alle relevanten Spalten aus vielen Tabellen. Die Endbenutzer greifen jedoch möglicherweise nur über eine Teilmenge der Tabellen in der Ansicht auf Spalten zu. Wenn die Tabellen mit äußeren Verknüpfungen verknüpft sind, kann (und tut) der Optimierer die nicht benötigten Tabellen aus dem Plan entfernen.

Es ist wichtig sicherzustellen, dass die Ansicht mit äußeren Verknüpfungen die richtigen Ergebnisse liefert. Wie Aaronaught gesagt hat - Sie können OUTER JOIN nicht blind durch INNER JOIN ersetzen und die gleichen Ergebnisse erwarten. Es kann jedoch vorkommen, dass dies aus Leistungsgründen bei der Verwendung von Ansichten hilfreich sein kann.

Ein letzter Hinweis: Ich habe die Auswirkungen auf die Leistung vor diesem Hintergrund nicht getestet, aber theoretisch sollten Sie in der Lage sein, einen INNER JOIN sicher durch einen OUTER JOIN zu ersetzen, wenn Sie auch die Bedingung <FOREIGN_KEY> IS NOT NULL hinzufügen zur where-Klausel.

Dbenham
quelle
5
Ich bin tatsächlich auf dieses Problem gestoßen, als ich extrem dynamische Abfragen erstellt habe. Ich war in einem INNER JOIN geblieben, den ich verwendet habe und aus dem ich keine Daten abgerufen habe, und als ich ihn aus Neugierde auf LEFT JOIN umgestellt habe, lief die Abfrage tatsächlich schneller.
Erik Philips
1
BEARBEITEN - Es wurden die Bedingungen geklärt, die vorhanden sein müssen, damit das Optimierungsprogramm die äußere verknüpfte Tabelle aus dem Ausführungsplan entfernt.
Dbenham
2
Eine kleine Klarstellung zu Ihrer Antwort: Wenn die Fremdschlüsselspalte nicht nullwertfähig ist, werden INNER JOIN und LEFT JOIN semantisch äquivalent (dh Ihre vorgeschlagene WHERE-Klausel ist redundant). Der einzige Unterschied wäre der Ausführungsplan.
Douglas
2
Obwohl dies tatsächlich ein scheinbar triviales Beispiel zeigt, ist dies eine außerordentlich aufschlussreiche Antwort!
Pbalaga
6
+1: Ich bin anscheinend bei einigen Abfragen darauf gestoßen, bei denen ich innere Verknüpfungen mit einigen sehr großen Tabellen verwendet habe. Der innere Join verursachte im Abfrageplan einen Überlauf in Tempdb (ich gehe aus dem oben genannten Grund davon aus - und meinem Server fehlt der RAM, um alles im Speicher zu halten). Durch das Wechseln zu linken Verknüpfungen wurde das Verschütten auf Tempdb beseitigt, sodass einige meiner Abfragen von 20 bis 30 Sekunden jetzt in Bruchteilen von Sekunden ausgeführt werden. Dies ist ein sehr wichtiger Punkt, da die meisten Leute die pauschale Annahme zu treffen scheinen, dass innere Verknüpfungen schneller sind.
Phosplait
23

Wenn alles so funktioniert, wie es sollte, sollte es nicht funktionieren, ABER wir alle wissen, dass nicht alles so funktioniert, wie es sollte, insbesondere wenn es um das Abfrageoptimierungsprogramm, das Zwischenspeichern von Abfrageplänen und Statistiken geht.

Zuerst würde ich vorschlagen, Index und Statistik neu zu erstellen und dann den Abfrageplan-Cache zu leeren, um sicherzustellen, dass dies nicht zu Problemen führt. Ich habe jedoch Probleme, selbst wenn das erledigt ist.

Ich habe einige Fälle erlebt, in denen eine linke Verknüpfung schneller war als eine innere Verknüpfung.

Der zugrunde liegende Grund ist folgender: Wenn Sie zwei Tabellen haben und einer Spalte mit einem Index beitreten (für beide Tabellen). Der innere Join führt zu demselben Ergebnis, unabhängig davon, ob Sie die Einträge im Index in Tabelle 1 durchlaufen und mit dem Index in Tabelle 2 übereinstimmen, als ob Sie das Gegenteil tun würden: Durchlaufen Sie die Einträge im Index in Tabelle 2 und stimmen Sie mit dem Index überein in Tabelle eins. Das Problem ist, wenn Sie irreführende Statistiken haben, verwendet das Abfrageoptimierungsprogramm die Statistiken des Index, um die Tabelle mit den am wenigsten übereinstimmenden Einträgen zu finden (basierend auf Ihren anderen Kriterien). Wenn Sie zwei Tabellen mit jeweils 1 Million haben, haben Sie in Tabelle eins 10 übereinstimmende Zeilen und in Tabelle zwei 100000 übereinstimmende Zeilen. Der beste Weg wäre, einen Index-Scan für Tabelle 1 durchzuführen und 10 Mal in Tabelle 2 abzugleichen. Die Umkehrung wäre ein Index-Scan, der über 100000 Zeilen durchläuft und versucht, 100000-mal übereinzustimmen, und nur 10 sind erfolgreich. Wenn die Statistik nicht korrekt ist, wählt der Optimierer möglicherweise die falsche Tabelle und den falschen Index für die Schleife aus.

Wenn der Optimierer die linke Verknüpfung in der Reihenfolge optimiert, in der sie geschrieben wurde, ist die Leistung besser als die der inneren Verknüpfung.

ABER der Optimierer kann auch einen linken Join suboptimal als linken Semi-Join optimieren. Um die gewünschte Auswahl zu treffen, können Sie den Force Order-Hinweis verwenden.

Kvasi
quelle
18

Probieren Sie beide Abfragen (die mit innerer und linker Verknüpfung) OPTION (FORCE ORDER)am Ende aus und veröffentlichen Sie die Ergebnisse. OPTION (FORCE ORDER)ist ein Abfragehinweis, der das Optimierungsprogramm zwingt, den Ausführungsplan mit der in der Abfrage angegebenen Verknüpfungsreihenfolge zu erstellen.

Wenn INNER JOINdie Leistung so schnell wie möglich beginnt LEFT JOIN, liegt dies daran:

  • In einer Abfrage, die vollständig aus INNER JOINs besteht, spielt die Verknüpfungsreihenfolge keine Rolle. Dies gibt dem Abfrageoptimierer die Freiheit, die Verknüpfungen nach eigenem Ermessen zu ordnen, sodass das Problem möglicherweise vom Optimierer abhängt.
  • Dies LEFT JOINist nicht der Fall, da durch Ändern der Verknüpfungsreihenfolge die Ergebnisse der Abfrage geändert werden. Dies bedeutet, dass die Engine der Join-Reihenfolge folgen muss, die Sie in der Abfrage angegeben haben. Diese ist möglicherweise besser als die optimierte.

Ich weiß nicht, ob dies Ihre Frage beantwortet, aber ich war einmal in einem Projekt mit hochkomplexen Abfragen, die Berechnungen durchführten, was den Optimierer völlig durcheinander brachte. Wir hatten Fälle, in denen a FORCE ORDERdie Ausführungszeit einer Abfrage von 5 Minuten auf 10 Sekunden verkürzte.

Francisco Pires
quelle
9

Haben eine Reihe von Vergleichen zwischen linken äußeren und inneren Verknüpfungen durchgeführt und konnten keinen konsistenten Unterschied feststellen. Es gibt viele Variablen. Ich arbeite an einer Berichtsdatenbank mit Tausenden von Tabellen, viele mit einer großen Anzahl von Feldern, vielen Änderungen im Laufe der Zeit (Herstellerversionen und lokaler Workflow). Es ist nicht möglich, alle Kombinationen von Deckungsindizes zu erstellen, um die Anforderungen einer derart großen Vielfalt von Abfragen zu erfüllen und historische Daten zu verarbeiten. Ich habe gesehen, dass innere Abfragen die Serverleistung beeinträchtigen, weil zwei große Tabellen (Millionen bis Zehntausende von Zeilen) innerlich verbunden sind und beide eine große Anzahl von Feldern ziehen und kein Deckungsindex vorhanden ist.

Das größte Problem scheint jedoch in den obigen Diskussionen nicht aufzutreten. Möglicherweise ist Ihre Datenbank mit Triggern und einer gut gestalteten Transaktionsverarbeitung gut gestaltet, um gute Daten zu gewährleisten. Meins hat häufig NULL-Werte, bei denen sie nicht erwartet werden. Ja, die Tabellendefinitionen könnten No-Nulls erzwingen, aber das ist in meiner Umgebung keine Option.

Die Frage ist also ... Entwerfen Sie Ihre Abfrage nur auf Geschwindigkeit, eine höhere Priorität für die Transaktionsverarbeitung, bei der derselbe Code tausende Male pro Minute ausgeführt wird. Oder streben Sie nach Genauigkeit, die eine linke äußere Verbindung bietet? Denken Sie daran, dass innere Verknüpfungen auf beiden Seiten Übereinstimmungen finden müssen, sodass ein unerwarteter NULL-Wert nicht nur Daten aus den beiden Tabellen, sondern möglicherweise ganze Informationszeilen entfernt. Und es passiert so schön, keine Fehlermeldungen.

Sie können sehr schnell 90% der benötigten Daten abrufen und nicht feststellen, dass die inneren Verknüpfungen Informationen stillschweigend entfernt haben. Manchmal können innere Verknüpfungen schneller sein, aber ich glaube nicht, dass jemand diese Annahme trifft, es sei denn, er hat den Ausführungsplan überprüft. Geschwindigkeit ist wichtig, aber Genauigkeit ist wichtiger.

JO
quelle
8

Ihre Leistungsprobleme sind eher auf die Anzahl der Verknüpfungen zurückzuführen, die Sie ausführen, und darauf, ob die Spalten, in denen Sie beitreten, Indizes haben oder nicht.

Im schlimmsten Fall könnten Sie leicht 9 ganze Tabellenscans für jeden Join durchführen.

eddiegroves
quelle
7

Äußere Verknüpfungen bieten in Ansichten eine überlegene Leistung.

Angenommen, Sie haben eine Abfrage, die eine Ansicht umfasst, und diese Ansicht besteht aus 10 miteinander verbundenen Tabellen. Angenommen, Ihre Abfrage verwendet nur Spalten aus 3 dieser 10 Tabellen.

Wenn diese 10 Tabellen innerlich zusammengefügt worden wären, müsste das Abfrageoptimierungsprogramm sie alle zusammenfügen, obwohl Ihre Abfrage selbst nicht 7 von 10 Tabellen benötigt. Dies liegt daran, dass die inneren Verknüpfungen selbst die Daten möglicherweise herausfiltern, sodass sie für die Berechnung unerlässlich sind.

Wenn diese 10 Tabellen stattdessen äußerlich zusammengefügt worden wären, würde das Abfrageoptimierungsprogramm tatsächlich nur die erforderlichen Tabellen zusammenfügen: 3 von 10 in diesem Fall. Dies liegt daran, dass die Joins selbst die Daten nicht mehr filtern und somit nicht verwendete Joins übersprungen werden können.

Quelle: http://www.sqlservercentral.com/blogs/sql_coach/2010/07/29/poor-little-misunderstood-views/

MarredCheese
quelle
1
Ihre Aussage zu "Outer-Joined" ist irreführend und möglicherweise falsch. Äußer bedeutet, dass die Daten auf der anderen Seite nicht vorhanden sein müssen - und wenn sie nicht NULL ersetzen. Unter bestimmten Umständen kann das RDBMS sie "überspringen" (siehe obige Antwort von dbenham). JEDOCH - Außen und Innen können dazu führen, dass Ihre Abfrage radikal unterschiedliche Ergebnisse liefert. INNER bedeutet - Geben Sie Ergebnisse an, für die sich ein Element in BEIDEN A & B befindet. LINKS AUSSEN bedeutet ganz A und optional B, falls vorhanden. Erster Fall - Sie erhalten einige Zeilen, im zweiten ALLE Zeilen.
Ripvlan
1
@ripvlan Natürlich sind äußere und innere Verknüpfungen nicht immer austauschbar. Die ursprüngliche Frage betraf die Leistung, was bedeutet, dass es sich um Fälle handelt, in denen jeder Join dieselbe Ergebnismenge zurückgibt.
MarredCheese
1
Ja und - OUTER kann ein Leistungsproblem verursachen, da alle Zeilen (mehr Daten) zurückgegeben werden. Ihre Annahme, dass die Abfragen zu derselben Ausgabe führen, ist fair - sie trifft jedoch im allgemeinen Fall nicht zu und ist für jedes Datenbankdesign spezifisch. Und für diejenigen, die nicht zu 100% mit relationaler Algebra vertraut sind, könnte dies Kummer verursachen. Mein Punkt ist nur, den Lesern, die nach Rat suchen, mehr Einblick zu geben und dass ein LINKS / RECHTS ein Problem nicht auf magische Weise löst und weitere Probleme verursachen könnte. Es ist eine Kraft für Level 300 übrig :-)
ripvlan
2

Ich fand etwas Interessantes in SQL Server, als ich überprüfte, ob innere Verknüpfungen schneller sind als linke Verknüpfungen.

Wenn Sie die Elemente der links verknüpften Tabelle nicht in die select-Anweisung aufnehmen, ist die linke Verknüpfung schneller als dieselbe Abfrage mit innerer Verknüpfung.

Wenn Sie die links verknüpfte Tabelle in die select-Anweisung aufnehmen, war der innere Join mit derselben Abfrage gleich oder schneller als der linke Join.

Buzzzzzzz
quelle
0

Aus meinen Vergleichen geht hervor, dass sie genau den gleichen Ausführungsplan haben. Es gibt drei Szenarien:

  1. Wenn und wann sie die gleichen Ergebnisse zurückgeben, haben sie die gleiche Geschwindigkeit. Wir müssen jedoch berücksichtigen, dass es sich nicht um dieselben Abfragen handelt und dass LEFT JOIN möglicherweise mehr Ergebnisse zurückgibt (wenn einige EIN-Bedingungen nicht erfüllt sind) - aus diesem Grund ist es normalerweise langsamer.

  2. Wenn die Haupttabelle (die erste nicht konstante im Ausführungsplan) eine einschränkende Bedingung hat (WHERE id =?) Und die entsprechende ON-Bedingung einen NULL-Wert hat, wird die "rechte" Tabelle nicht verbunden - dies ist der Zeitpunkt LEFT JOIN ist schneller.

  3. Wie in Punkt 1 erläutert, ist INNER JOIN normalerweise restriktiver und liefert weniger Ergebnisse und ist daher schneller.

Beide verwenden (dieselben) Indizes.

Jiulin Teng
quelle