Я не думаю, що це має щось спільне з тим, що ти страшенно повільний; це стосується того, щоб бути потенційно неточним. Наприклад, з урахуванням наступних даних - замовлення, які можна оформити або окремим клієнтом, або партнером 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);
Скажімо, я хочу знайти всіх клієнтів, які ніколи не розміщували замовлення. З огляду на дані, є лише одне: клієнт №2. Ось три способи написати запит, щоб знайти цю інформацію (є й інші):
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;
Результати:
NOT IN
------
-- <-- no results. Is that what you expected?
NOT EXISTS
----------
2
EXCEPT
------
2
Зараз також є деякі проблеми з продуктивністю, і я про них говорю в цій публікації в блозі . Залежно від даних та індексів, NOT EXISTS
зазвичай , вони будуть перевершувати NOT IN
, і я не знаю, чи може вона колись погіршитися. Слід також зазначити, що EXCEPT
можна ввести чітку операцію сортування, тому ви можете отримати різні дані (знову ж таки, залежно від джерела). І що популярний LEFT OUTER JOIN ... WHERE right.column IS NULL
зразок завжди найгірший виконавець.
У Мартіна Сміта є багато хорошої допоміжної інформації у своїй відповіді на ТА .
IN
/NOT IN
завжди буде реалізовуватися за допомогою вкладених циклів. І я поняття не маю, щоstops SQL Server from creating a ‘plan’
має означати.