Ich bin gespannt, welche der folgenden Möglichkeiten effizienter ist.
Ich war immer etwas vorsichtig bei der Verwendung, IN
weil ich glaube, dass SQL Server die Ergebnismenge in eine große IF
Aussage verwandelt . Bei einer großen Ergebnismenge kann dies zu einer schlechten Leistung führen. Bei kleinen Ergebnismengen bin ich mir nicht sicher, ob dies auch vorzuziehen ist. Wäre es für große Ergebnismengen nicht EXISTS
effizienter?
WHERE EXISTS (SELECT * FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
vs.
WHERE bx.BoxID IN (SELECT BoxID FROM Base WHERE [Rank = 2])
sql-server
sql-server-2005
exists
query-performance
sql-in
Randy Minder
quelle
quelle
select 1 from Base...
in Ihremwhere exists
da Sie eigentlich gar nicht über die Ergebnisse kümmern, nur , dass eine Reihe tatsächlich existiert.Antworten:
EXISTS
wird schneller sein, denn sobald der Motor einen Treffer gefunden hat, hört er auf zu schauen, da sich der Zustand als wahr erwiesen hat.Mit
IN
werden alle Ergebnisse der Unterabfrage vor der weiteren Verarbeitung erfasst.quelle
Die akzeptierte Antwort ist kurzsichtig und die Frage etwas locker:
Ich glaube, der Optimierer ist intelligent genug, um zwischen "in" und "existiert" zu konvertieren, wenn aufgrund von (1) und (2) ein erheblicher Kostenunterschied besteht, andernfalls kann er nur als Hinweis verwendet werden (z. B. existiert, um die Verwendung von zu fördern) ein suchbarer Index auf der rechten Seite).
Beide Formulare können intern in Verknüpfungsformulare konvertiert, die Verknüpfungsreihenfolge umgekehrt und als Schleife, Hash oder Zusammenführung ausgeführt werden - basierend auf den geschätzten Zeilenzahlen (links und rechts) und der Indexexistenz auf der linken, rechten oder beiden Seiten.
quelle
IN
undEXISTS
. Versuchen Sie, einen Fall zu finden, in dem sie nicht den gleichen Plan erhalten (obwohl dies nicht fürNOT IN
und giltNOT EXISTS
)Ich habe einige Tests mit SQL Server 2005 und 2008 durchgeführt, und sowohl auf EXISTS als auch auf IN wird genau derselbe tatsächliche Ausführungsplan verwendet, wie andere angegeben haben. Der Optimierer ist optimal. :) :)
Beachten Sie jedoch, dass EXISTS, IN und JOIN manchmal unterschiedliche Ergebnisse zurückgeben können, wenn Sie Ihre Abfrage nicht richtig formulieren: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210 .aspx
quelle
Hier gibt es viele irreführende Antworten, einschließlich der hoch bewerteten Antworten (obwohl ich nicht glaube, dass ihre Operationen Schaden anrichteten). Die kurze Antwort lautet: Diese sind gleich.
Es gibt viele Schlüsselwörter in der (T-) SQL-Sprache, aber am Ende passieren auf der Hardware nur die Vorgänge, die im Ausführungsabfrageplan aufgeführt sind.
Die relationale (Mathematik Theorie) Operation , die wir tun , wenn wir berufen
[NOT] IN
und[NOT] EXISTS
ist die halb join (anti-beitreten bei der VerwendungNOT
). Es ist kein Zufall, dass die entsprechenden SQL Server-Vorgänge denselben Namen haben . Es gibt keine Operation, die erwähntIN
oderEXISTS
irgendwo - nur (Anti-) Semi-Joins. Somit gibt es keine Möglichkeit , dass ein logisch-äquivalentIN
vsEXISTS
Wahl Leistung beeinträchtigen könnte , weil es eine gibt und einzigen Weg, die (anti) halbAusführungsOperation teilnehmen, um ihre Ergebnisse zu erhalten .Ein Beispiel:
Abfrage 1 ( Plan )
Abfrage 2 ( Plan )
quelle
Ich würde mit EXISTS über IN gehen, siehe untenstehenden Link:
SQL Server: JOIN vs IN vs EXISTS - der logische Unterschied
Blog-Gutschrift: https://stackoverflow.com/users/31345/mladen-prajdic
quelle
Die Ausführungspläne sind in diesen Fällen normalerweise identisch, aber bis Sie sehen, wie der Optimierer alle anderen Aspekte von Indizes usw. berücksichtigt, werden Sie es wirklich nie erfahren.
quelle
IN ist also nicht dasselbe wie EXISTS und erzeugt auch nicht denselben Ausführungsplan.
Normalerweise wird EXISTS in einer korrelierten Unterabfrage verwendet. Dies bedeutet, dass Sie die innere EXISTS-Abfrage mit Ihrer äußeren Abfrage verbinden. Dadurch werden weitere Schritte hinzugefügt, um ein Ergebnis zu erzielen, da Sie die äußeren Abfrageverknüpfungen und die inneren Abfrageverknüpfungen lösen müssen und dann mit den where-Klauseln übereinstimmen, um beide zu verbinden.
Normalerweise wird IN verwendet, ohne die innere Abfrage mit der äußeren Abfrage zu korrelieren, und dies kann in nur einem Schritt gelöst werden (im besten Fall).
Bedenken Sie:
Wenn Sie IN verwenden und das Ergebnis der inneren Abfrage Millionen von Zeilen mit unterschiedlichen Werten enthält, wird es wahrscheinlich langsamer als EXISTS ausgeführt, da die EXISTS-Abfrage performant ist (über die richtigen Indizes verfügt, um mit der äußeren Abfrage zu verknüpfen).
Wenn Sie EXISTS verwenden und der Join mit Ihrer äußeren Abfrage komplex ist (die Ausführung dauert länger, keine geeigneten Indizes), wird die Abfrage um die Anzahl der Zeilen in der äußeren Tabelle verlangsamt. Manchmal kann die geschätzte Zeit bis zum Abschluss in Tagen liegen. Wenn die Anzahl der Zeilen für die angegebene Hardware akzeptabel ist oder die Kardinalität der Daten korrekt ist (z. B. weniger DISTINCT-Werte in einem großen Datensatz), kann IN schneller als EXISTS ausgeführt werden.
All dies wird beachtet, wenn Sie eine angemessene Anzahl von Zeilen in jeder Tabelle haben (mit fair meine ich etwas, das Ihre CPU-Verarbeitung und / oder RAM-Schwellenwerte für das Caching überschreitet).
Die ANTWORT ist also ABHÄNGIG. Sie können eine komplexe Abfrage in IN oder EXISTS schreiben. Als Faustregel sollten Sie jedoch versuchen, IN mit einer begrenzten Anzahl unterschiedlicher Werte und EXISTS zu verwenden, wenn Sie viele Zeilen mit vielen unterschiedlichen Werten haben.
Der Trick besteht darin, die Anzahl der zu scannenden Zeilen zu begrenzen.
Grüße,
MarianoC
quelle
Um das zu optimieren
EXISTS
, sei sehr wörtlich; Es muss nur etwas vorhanden sein, aber Sie benötigen keine Daten, die von der korrelierten Unterabfrage zurückgegeben werden. Sie bewerten nur eine boolesche Bedingung.So:
WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)
Da die korrelierte Unterabfrage lautet
RBAR
, erfüllt der erste Ergebnistreffer die Bedingung und wird nicht weiter verarbeitet.quelle
Aus dem Kopf und nicht garantiert richtig: Ich glaube, der zweite wird in diesem Fall schneller sein.
IN
Wille kurzgeschlossen, sobald eine Übereinstimmung gefunden wird.quelle