تفاوت 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 تعبیر می شود و هیچ رکوردی بازگردانده نخواهد شد.