Frage

Ich bin gespannt, welche der folgenden folgenden folgenden Aussagen effizienter sein würden?

Ich war schon immer ein bisschen vorsichtig bei der Verwendung IN Weil ich glaube, SQL Server verwandelt das Ergebnis in eine große IF Aussage. Für ein großes Ergebnissatz könnte dies zu einer schlechten Leistung führen. Bei kleinen Ergebnismengen bin ich mir auch nicht sicher, ob es auch vorzuziehen ist. Für große Ergebnisse würde es nicht tun EXISTS effizienter sein?

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])
War es hilfreich?

Lösung

EXISTS wird schneller sein, denn sobald der Motor einen Treffer gefunden hat, wird er aufhören, auszusehen, da sich die Bedingung als wahr erwiesen hat.

Mit IN, Es sammelt alle Ergebnisse aus dem Unterbild vor der weiteren Verarbeitung.

Andere Tipps

Die akzeptierte Antwort ist kurzsichtig und die Frage ein bisschen locker darin:

1) weder ausdrücklich erwähnen, ob ein Deckungsindex links, rechts oder beide Seiten vorhanden ist.

2) Die Größe des Eingangssatzes für die linke Seite und Eingabe der rechten Seite berücksichtigt nicht.
(Die Frage erwähnt nur insgesamt groß Ergebnis einstellen).

Ich glaube ein suchbarer Index auf der rechten Seite).

Beide Formulare können in interne Formulare konvertiert werden, die Join-Reihenfolge umgekehrt und als Schleife, Hash oder Merge-basiert auf den geschätzten Zeilenzahlen (links und rechts) und in der Existenz von links, rechts oder beiden Seiten ausgeführt werden.

Ich habe einige Tests auf SQL Server 2005 und 2008 sowie auf beiden existieren und in der in den gleichen tatsächlichen Ausführungsplan wie andere vorgenommen. Der Optimierer ist optimal. :)

Es gibt jedoch etwas, über das man sich bewusst ist, existiert, in und Join kann manchmal verschiedene Ergebnisse zurückgeben, wenn Sie Ihre Abfrage nicht genau richtig formulieren: http://weblogs.sqlteam.com/mladenp/archive/2007/05/18/60210.aspx

Ich würde mit existieren, siehe unten Link:

SQL Server: Join VS in VS existiert - der logische Unterschied

Die Ausführungspläne werden in diesen Fällen in der Regel identisch sein.

In ist also weder das gleiche wie existiert noch wird es den gleichen Ausführungsplan erstellen.

Normalerweise wird in einer korrelierten Unterabfrage verwendet, dh Sie werden sich der existierenden inneren Abfrage mit Ihrer äußeren Abfrage anschließen. Dies fügt weitere Schritte hinzu, um ein Ergebnis zu erzielen, da Sie die Outer -Abfragesanschlüsse lösen müssen, und die innere Abfrageverbindungen entsprechen dann ihren Where -Klauseln, um sich beides zu verbinden.

Normalerweise wird in verwendet, ohne die innere Abfrage mit der äußeren Abfrage zu korrelieren, und dies kann nur in einem Schritt gelöst werden (im besten Fallszenario).

Bedenken Sie:

  1. Wenn Sie in und das innere Abfrageergebnis Millionen von Zeilen unterschiedlicher Werte sind, wird es wahrscheinlich langsamer als existiert, da die existierende Abfrage leistungsfähig ist (hat die richtigen Indizes, um sich der äußeren Abfrage anzuschließen).

  2. Wenn Sie vorhanden sind und der Verbinde mit Ihrer äußeren Abfrage komplex ist (es dauert mehr Zeit für die Ausführung, keine geeigneten Indizes), verlangsamt die Abfrage die Anzahl der Zeilen in der Außentabelle, manchmal kann die geschätzte Zeit bis hin zu Tagen dauern. Wenn die Anzahl der Zeilen für Ihre gegebene Hardware akzeptabel ist oder die Kardinalität der Daten korrekt ist (z. B. weniger unterschiedliche Werte in einem großen Datensatz) können schneller als existiert werden.

  3. Alle oben genannten werden angemerkt, wenn Sie auf jeder Tabelle eine angemessene Anzahl von Zeilen haben (mit Fair meine ich etwas, das Ihre CPU -Verarbeitungs- und/oder RAM -Schwellenwerte für das Caching überschreitet).

Die Antwort lautet also, dass es hängt. Sie können eine komplexe Abfrage innerhalb oder existieren schreiben, aber als Faustregel sollten Sie versuchen, mit einem begrenzten Satz unterschiedlicher Werte und existieren, wenn Sie viele Zeilen mit vielen unterschiedlichen Werten haben.

Der Trick besteht darin, die Anzahl der zu scannten Zeilen zu begrenzen.

Grüße,

Marianoc

Um die zu optimieren EXISTS, sei sehr wörtlich; Etwas muss nur da sein, aber Sie benötigen eigentlich keine Daten, die aus dem korrelierten Unterbild zurückgegeben werden. Sie bewerten nur einen booleschen Zustand.

So:

WHERE EXISTS (SELECT TOP 1 1 FROM Base WHERE bx.BoxID = Base.BoxID AND [Rank] = 2)

Weil der korrelierte Unterbild ist RBAR, Das erste Ergebnis Treffer macht die Bedingung zutreffend und wird nicht weiter verarbeitet.

Hier gibt es viele irreführende Antworten, einschließlich des hochrangigen (obwohl ich nicht glaube, dass ihre OPS Schaden bedeuten). Die kurze Antwort lautet: Diese sind gleich.

Es gibt viele Schlüsselwörter in der (T-) SQL-Sprache, aber am Ende ist das einzige, was wirklich auf der Hardware passiert, die Vorgänge, wie im Ausführungsabfrageplan zu sehen.

Die relationale (Maths -Theorie) Operation, die wir durchrufen, wenn wir aufrufen [NOT] IN und [NOT] EXISTS ist das Semi-Join (Anti-Join bei Verwendung NOT). Es ist kein Zufall, dass die entsprechenden SQL-Server-Operationen haben der selbe Name. Es gibt keine Operation, die erwähnt IN oder EXISTS Überall - nur (Anti-) Semi -Verbindungen. Daher, Es gibt keine Möglichkeit, logisch äquivalent zu sein IN vs EXISTS Die Auswahl könnte die Leistung beeinflussen, da es einen und einzigen Weg gibt, den (Anti) Semi -Join -Ausführungsoperation, um ihre Ergebnisse zu erzielen.

Ein Beispiel:

Abfrage 1 ( planen )

select * from dt where dt.customer in (select c.code from customer c where c.active=0)

Abfrage 2 ( planen )

select * from dt where exists (select 1 from customer c where c.code=dt.customer and c.active=0)

Ab meinem Kopf und nicht garantiert, dass er korrekt ist: Ich glaube, die zweite wird in diesem Fall schneller sein.

  1. Im ersten Fall wird die korrelierte Unterabfrage wahrscheinlich dazu führen, dass die Unterabfrage für jede Zeile ausgeführt wird.
  2. Im zweiten Beispiel sollte die Unterabfrage nur einmal ausgeführt werden, da nicht korreliert.
  3. Im zweiten Beispiel die IN Will Kurzschluss, sobald es ein Match findet.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top