Je ne pense pas que cela ait à voir avec le fait d'être terriblement lent; cela a à voir avec le fait d'être potentiellement inexact. Par exemple, compte tenu des données suivantes - commandes pouvant être passées soit par un client individuel, soit par un partenaire B2B:
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);
Disons que je veux trouver tous les clients qui n'ont jamais passé de commande. Compte tenu des données, il n'y en a qu'un: le client n ° 2. Voici trois façons de rédiger une requête pour trouver ces informations (il y en a d'autres):
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;
Résultats:
NOT IN
------
-- <-- no results. Is that what you expected?
NOT EXISTS
----------
2
EXCEPT
------
2
Maintenant, il y a aussi des problèmes de performances, et j'en parle dans ce blog . En fonction des données et des index, NOT EXISTS
il surclasse généralement les performances NOT IN
, et je ne sais pas si cela pourrait se dégrader. Vous devez également noter que cela EXCEPT
peut introduire une opération de tri distincte, vous pouvez donc vous retrouver avec des données différentes (encore une fois, selon la source). Et que le LEFT OUTER JOIN ... WHERE right.column IS NULL
modèle populaire est toujours le moins performant.
Martin Smith a également beaucoup de bonnes informations à l'appui dans sa réponse sur SO .
IN
/NOT IN
sera toujours implémenté avec des boucles imbriquées. Et je n'ai aucune idée de ce quistops SQL Server from creating a ‘plan’
est censé signifier.