Ich glaube nicht, dass es etwas damit zu tun hat, schrecklich langsam zu sein. es hat damit zu tun, dass es möglicherweise ungenau ist. Zum Beispiel mit den folgenden Daten - Bestellungen, die entweder von einem einzelnen Kunden oder einem B2B-Partner aufgegeben werden könnten:
DECLARE @Customers TABLE(CustomerID INT);
INSERT @Customers VALUES(1),(2);
DECLARE @Orders TABLE(OrderID INT, CustomerID INT, CompanyID INT);
INSERT @Orders VALUES(10,1,NULL),(11,NULL,5);
Angenommen, ich möchte alle Kunden finden, die noch nie eine Bestellung aufgegeben haben. In Anbetracht der Daten gibt es nur einen: Kunde 2. Es gibt drei Möglichkeiten, wie ich eine Abfrage schreiben kann, um diese Informationen zu finden (es gibt andere):
SELECT [NOT IN] = CustomerID FROM @Customers
WHERE CustomerID NOT IN (SELECT CustomerID FROM @Orders);
SELECT [NOT EXISTS] = CustomerID FROM @Customers AS c
WHERE NOT EXISTS (SELECT 1 FROM @Orders AS o
WHERE o.CustomerID = c.CustomerID);
SELECT [EXCEPT] = CustomerID FROM @Customers
EXCEPT SELECT CustomerID FROM @Orders;
Ergebnisse:
NOT IN
------
-- <-- no results. Is that what you expected?
NOT EXISTS
----------
2
EXCEPT
------
2
Nun gibt es auch einige Leistungsprobleme, über die ich in diesem Blogeintrag spreche . Abhängig von den Daten und Indizes NOT EXISTS
wird in der Regel eine Outperformance NOT IN
erzielt, und ich weiß nicht, ob sich die Leistung jemals verschlechtern könnte. Sie sollten auch beachten, dass EXCEPT
eine bestimmte Sortieroperation eingeführt werden kann, sodass Sie möglicherweise unterschiedliche Daten erhalten (wiederum abhängig von der Quelle). Und dass das beliebte LEFT OUTER JOIN ... WHERE right.column IS NULL
Muster immer das schlechteste ist.
Martin Smith hat auch in seiner Antwort auf SO eine Menge guter Hintergrundinformationen .
IN
/NOT IN
immer mit verschachtelten Schleifen implementiert wird. Und ich habe keine Ahnung, wasstops SQL Server from creating a ‘plan’
das bedeuten soll.