تفاوت NOT IN و NOT EXISTS در SQL
در SQL، دو دستور NOT IN
و NOT EXISTS
برای فیلتر کردن نتایج استفاده میشوند. در اینجا به بررسی دو کوئری مختلف و مقایسه سرعت و کارایی آنها میپردازیم.
فرض کنید می خواهیم محصولاتی را از جدول Products
پیدا کنیم که سفارشی برای آنها در جدول Order Details
ثبت نشده است:
- با استفاده از
NOT EXISTS
:
SELECT ProductID, ProductName
FROM Northwind.Products p
WHERE NOT EXISTS (
SELECT 1
FROM Northwind.[Order Details] od
WHERE p.ProductId = od.ProductId
)
- با استفاده از
NOT IN
:
SELECT ProductID, ProductName
FROM Northwind.Products p
WHERE p.ProductID NOT IN (
SELECT ProductID
FROM Northwind.[Order Details])
مقایسه کارایی
به طور کلی، اگرچه برنامهریزی اجرای کوئریها ممکن است نشان دهد که این دو دستور یک عملکرد مشابه دارند، اما در موارد خاص، تفاوتهایی در رفتار آنها به ویژه در حضور مقادیر NULL
وجود دارد.
تاثیر مقادیر NULL
یکی از نکات کلیدی که در اینجا وجود دارد این است که اگر در زیر کوئری NOT IN
حداقل یک مقدار NULL
وجود داشته باشد، نتایج قابل اعتماد نخواهد بود. به عبارت دیگر، اگر هر رکوردی در زیر کوئری حاوی NULL
باشد، کوئری NOT IN
هیچ رکوردی را بازنخواهد گرداند. این به این دلیل است که عملگر NOT IN
با مقادیر NULL
به گونهای رفتار میکند که موجب میشود آن مقادیر به طور کلی در محاسبه نتایج نادیده گرفته شوند.
در عوض، NOT EXISTS
در مواجهه با NULL
ها رفتار قابل پیشبینیتری دارد و به طور کلی بهتر از NOT IN
عمل میکند. در برنامههایی که ممکن است در آینده تغییر کنند یا مقادیر NULL
اضافی داشته باشند، انتخاب NOT EXISTS
ایمنتر است.
برای مثال کوئری زیر:
select 1 where 3 not in (1, 2, null)
معادل کوئری زیر می باشد:
select 'true' where 3 <> 1 and 3 <> 2 and 3 <> null
و زمانی که مقدار تنظیمات ansi_nulls
برابر با on
باشد عبارت 3 <> null
به UNKNOWN
تعبیر می شود و هیچ رکوردی بازگردانده نخواهد شد.