Ich möchte wissen, ob ich eine Join- Abfrage wie diese habe -
Select E.Id,E.Name from Employee E join Dept D on E.DeptId=D.Id
und eine Unterabfrage wie diese -
Select E.Id,E.Name from Employee Where DeptId in (Select Id from Dept)
Wenn ich die Leistung betrachte, welche der beiden Abfragen wäre schneller und warum ?
Gibt es auch eine Zeit, in der ich eine der anderen vorziehen sollte?
Tut mir leid, wenn dies zu trivial ist und vorher gefragt wurde, aber ich bin verwirrt darüber. Außerdem wäre es großartig, wenn ihr mir Tools vorschlagen könnt, mit denen ich die Leistung von zwei Abfragen messen sollte. Vielen Dank!
sql
performance
sql-server-2008
subquery
join
Vishal
quelle
quelle
Antworten:
Ich würde erwarten, dass die erste Abfrage schneller ist, hauptsächlich weil Sie eine Äquivalenz und einen expliziten JOIN haben. Nach meiner Erfahrung
IN
ist dies ein sehr langsamer Operator, da SQL ihn normalerweise als eine Reihe vonWHERE
Klauseln auswertet , die durch "ODER" (WHERE x=Y OR x=Z OR...
) getrennt sind.Wie bei ALL THINGS SQL kann Ihr Kilometerstand jedoch variieren. Die Geschwindigkeit hängt unter anderem stark von Indizes ab (haben Sie Indizes für beide ID-Spalten? Das hilft sehr ...).
Die einzige WIRKLICHE Möglichkeit, mit 100% iger Sicherheit festzustellen, was schneller ist, besteht darin, die Leistungsverfolgung zu aktivieren (E / A-Statistik ist besonders nützlich) und beide auszuführen. Stellen Sie sicher, dass Sie Ihren Cache zwischen den Läufen leeren!
quelle
Nun, ich glaube, es ist eine "Alt aber Gold" -Frage. Die Antwort lautet: "Es kommt darauf an!". Die Aufführungen sind ein so heikles Thema, dass es zu dumm wäre zu sagen: "Niemals Unterabfragen verwenden, immer mitmachen". Unter den folgenden Links finden Sie einige grundlegende Best Practices, die ich als sehr hilfreich empfunden habe:
Ich habe eine Tabelle mit 50000 Elementen, das Ergebnis, das ich suchte, war 739 Elemente.
Meine Frage war zunächst:
Die Ausführung dauerte 7,9 Sekunden.
Meine Frage lautet endlich:
und es dauerte 0,0256s
Gutes SQL, gut.
quelle
Sehen Sie sich die Ausführungspläne an, um festzustellen, wie unterschiedlich der SQl-Server sie interpretiert. Sie können Profiler auch verwenden, um die Abfragen tatsächlich mehrmals auszuführen und den Unterschied zu ermitteln.
Ich würde nicht erwarten, dass diese so schrecklich unterschiedlich sind, wenn Sie echte, große Leistungssteigerungen bei der Verwendung von Joins anstelle von Unterabfragen erzielen, wenn Sie korrelierte Unterabfragen verwenden.
EXISTS ist oft besser als eine dieser beiden und wenn Sie über linke Joins sprechen, bei denen Sie alle Datensätze möchten, die nicht in der linken Join-Tabelle enthalten sind, ist NOT EXISTS oft eine viel bessere Wahl.
quelle
Die Leistung basiert auf der Datenmenge, mit der Sie ...
Wenn es weniger Daten um 20k sind. JOIN funktioniert besser.
Wenn die Daten eher 100k + entsprechen, funktioniert IN besser.
Wenn Sie die Daten aus der anderen Tabelle nicht benötigen, ist IN gut, aber es ist immer besser, EXISTS zu wählen.
Alle diese Kriterien habe ich getestet und die Tabellen haben die richtigen Indizes.
quelle
Die Leistung sollte gleich sein; Es ist viel wichtiger, dass die richtigen Indizes und Clustering auf Ihre Tabellen angewendet werden ( zu diesem Thema gibt es einige gute Ressourcen ).
(Bearbeitet, um die aktualisierte Frage widerzuspiegeln)
quelle
Die beiden Abfragen sind möglicherweise nicht semantisch äquivalent. Wenn ein Mitarbeiter für mehr als eine Abteilung arbeitet (möglich in dem Unternehmen, für das ich arbeite; dies würde zugegebenermaßen bedeuten, dass Ihre Tabelle nicht vollständig normalisiert ist), würde die erste Abfrage doppelte Zeilen zurückgeben, während die zweite Abfrage dies nicht tun würde. Um die Abfragen in diesem Fall gleichwertig zu machen,
DISTINCT
müsste das Schlüsselwort zurSELECT
Klausel hinzugefügt werden , was sich auf die Leistung auswirken kann.Beachten Sie, dass es eine Entwurfsregel gibt, die besagt, dass eine Tabelle eine Entität / Klasse oder eine Beziehung zwischen Entitäten / Klassen modellieren soll, jedoch nicht beide. Daher schlage ich vor, dass Sie beispielsweise eine dritte Tabelle erstellen
OrgChart
, um die Beziehung zwischen Mitarbeitern und Abteilungen zu modellieren.quelle
Ich weiß, dass dies ein alter Beitrag ist, aber ich denke, dass dies ein sehr wichtiges Thema ist, insbesondere heutzutage, wo wir über 10 Millionen Datensätze haben und über Terabytes an Daten sprechen.
Ich werde auch auf die folgenden Beobachtungen eingehen. Ich habe ungefähr 45 Millionen Datensätze in meiner Tabelle ([Daten]) und ungefähr 300 Datensätze in meiner [Katzen] -Tabelle. Ich habe eine umfangreiche Indizierung für alle Abfragen, über die ich sprechen werde.
Betrachten Sie Beispiel 1:
versus Beispiel 2:
Beispiel 1 dauerte ungefähr 23 Minuten, um zu laufen. Beispiel 2 dauerte ungefähr 5 Minuten.
Daher würde ich zu dem Schluss kommen, dass die Unterabfrage in diesem Fall viel schneller ist. Denken Sie natürlich daran, dass ich M.2-SSD-Laufwerke verwende, die E / A mit 1 GB / s unterstützen (das sind Bytes, keine Bits), daher sind meine Indizes auch sehr schnell. Dies kann sich also unter Ihren Umständen auch auf die Geschwindigkeit auswirken
Wenn es sich um eine einmalige Datenbereinigung handelt, lassen Sie sie wahrscheinlich am besten laufen und beenden. Ich verwende TOP (10000) und sehe, wie lange es dauert, und multipliziere mit der Anzahl der Datensätze, bevor ich die große Abfrage treffe.
Wenn Sie Produktionsdatenbanken optimieren, würde ich dringend empfehlen, Daten vorzuverarbeiten, dh Trigger oder Job-Broker zu verwenden, um Aktualisierungsdatensätze zu asynchronisieren, damit der Echtzeitzugriff statische Daten abruft.
quelle
Sie können einen Erklärungsplan verwenden, um eine objektive Antwort zu erhalten.
Für Ihr Problem würde ein Exists-Filter wahrscheinlich die schnellste Leistung erbringen.
quelle