Aktualizacja:
Te artykuły na moim blogu bardziej szczegółowo opisują różnice między metodami:
Takie zapytanie można wykonać na trzy sposoby:
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
)
Gdy table1.common_idnie dopuszcza wartości null, wszystkie te zapytania są semantycznie takie same.
Kiedy jest dopuszczalna wartość null, NOT INjest różna, ponieważ IN(i dlatego NOT IN) zwraca, NULLgdy wartość nie pasuje do niczego na liście zawierającej NULL.
Może to być mylące, ale może stać się bardziej oczywiste, jeśli przypomnimy sobie alternatywną składnię tego:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
Wynik tego warunku jest logicznym iloczynem wszystkich porównań na liście. Oczywiście pojedyncza NULLwartość daje NULLwynik, który renderuje również cały wynik NULL.
Nigdy nie możemy z całą pewnością stwierdzić, że common_idnie jest to coś z tej listy, ponieważ przynajmniej jedna z wartości to NULL.
Załóżmy, że mamy te dane:
common
1
3
table1
NULL
1
2
LEFT JOIN / IS NULLi NOT EXISTSzwróci 3, NOT INnie zwróci nic (ponieważ zawsze będzie zwracać wartość albo FALSElub NULL).
W MySQLprzypadku, gdy kolumna nie dopuszcza wartości null LEFT JOIN / IS NULLi NOT INsą nieco (kilka procent) wydajniejsze niż NOT EXISTS. Jeśli kolumna dopuszcza wartość null, NOT EXISTSjest najbardziej wydajna (znowu niewiele).
W programie Oraclewszystkie trzy zapytania dają takie same plany (an ANTI JOIN).
W SQL Server, NOT IN/ NOT EXISTSsą bardziej wydajne, ponieważ LEFT JOIN / IS NULLnie mogą być zoptymalizowane do an ANTI JOINprzez jego optymalizator.
W PostgreSQL, LEFT JOIN / IS NULLi NOT EXISTSsą bardziej skuteczne niż NOT INsinus są zoptymalizowane Anti Join, podczas NOT INzastosowania hashed subplan(lub nawet gładkie subplanczy podkwerendę jest zbyt duża, aby hash)