Saya tidak berpikir itu ada hubungannya dengan menjadi sangat lambat; itu ada hubungannya dengan menjadi berpotensi tidak akurat. Misalnya, diberi data berikut - pesanan yang dapat ditempatkan baik oleh pelanggan individu, atau mitra 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);
Katakanlah saya ingin menemukan semua pelanggan yang belum pernah melakukan pemesanan. Mengingat data, hanya ada satu: pelanggan # 2. Berikut adalah tiga cara yang dapat saya lakukan untuk menulis kueri untuk menemukan informasi itu (ada yang lain):
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;
Hasil:
NOT IN
------
-- <-- no results. Is that what you expected?
NOT EXISTS
----------
2
EXCEPT
------
2
Sekarang, ada beberapa masalah kinerja juga, dan saya membicarakannya di posting blog ini . Tergantung pada data dan indeks, NOT EXISTS
biasanya akan mengungguli NOT IN
, dan saya tidak tahu apakah itu bisa berkinerja lebih buruk. Anda juga harus mencatat bahwa EXCEPT
dapat memperkenalkan operasi penyortiran yang berbeda, sehingga Anda dapat berakhir dengan data yang berbeda (sekali lagi, tergantung pada sumbernya). Dan bahwa LEFT OUTER JOIN ... WHERE right.column IS NULL
pola populer selalu merupakan yang terburuk.
Martin Smith juga memiliki banyak informasi pendukung yang bagus dalam jawabannya di SO .
IN
/NOT IN
akan selalu diimplementasikan dengan loop bersarang. Dan saya tidak tahu apastops SQL Server from creating a ‘plan’
yang dimaksudkan.