Güncelleme:
Blogumdaki bu makaleler, yöntemler arasındaki farkları daha ayrıntılı olarak açıklamaktadır:
Böyle bir sorgu yapmanın üç yolu vardır:
LEFT JOIN / IS NULL
:
SELECT *
FROM common
LEFT JOIN
table1 t1
ON t1.common_id = common.common_id
WHERE t1.common_id IS NULL
NOT EXISTS
:
SELECT *
FROM common
WHERE NOT EXISTS
(
SELECT NULL
FROM table1 t1
WHERE t1.common_id = common.common_id
)
NOT IN
:
SELECT *
FROM common
WHERE common_id NOT IN
(
SELECT common_id
FROM table1 t1
)
Ne zaman table1.common_id
null değil, bütün bu sorgular anlamsal aynıdır.
Boş değer atanabilir olduğunda NOT IN
, farklıdır, çünkü IN
(ve bu nedenle NOT IN
) NULL
bir değer, bir NULL
.
Bu kafa karıştırıcı olabilir, ancak bunun için alternatif sözdizimini hatırlarsak daha açık hale gelebilir:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
Bu koşulun sonucu, listedeki tüm karşılaştırmaların bir mantıksal ürünüdür. Tabii ki, tek bir NULL
değer NULL
sonucu da verir, bu da tüm sonucu verir NULL
.
common_id
Değerlerden en az biri olduğu için, kesinlikle bu listedeki hiçbir şeye eşit olmadığını söyleyemeyiz NULL
.
Şu verilere sahip olduğumuzu varsayalım:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN / IS NULL
ve NOT EXISTS
geri dönecek 3
, hiçbir şeyNOT IN
döndürmeyecek (çünkü her zaman ya da olarak değerlendirilecektir ).FALSE
NULL
In MySQL
, non-nullable sütun üzerinde LEFT JOIN / IS NULL
ve NOT IN
biraz (birkaç yüzde) daha etkilidir NOT EXISTS
. Sütun boş değer atanabilirse, NOT EXISTS
en verimli olanıdır (yine çok değil).
İçinde Oracle
, üç sorgu da aynı planları (an ANTI JOIN
) verir.
İn SQL Server
, NOT IN
/ NOT EXISTS
are daha verimlidir, çünkü LEFT JOIN / IS NULL
optimize edicisi ANTI JOIN
tarafından bir için optimize edilemez .
İçinde PostgreSQL
, LEFT JOIN / IS NULL
ve NOT EXISTS
daha verimli NOT IN
, onlar için optimize edilmiştir sinüs Anti Join
ise, NOT IN
kullanım hashed subplan
(ya da bir düz subplan
alt sorgu karma için çok büyük ise)