Aktualizacja:
te artykuły w blogu opisać różnice między metodami w bardziej szczegół:
Istnieją trzy sposoby, aby zrobić takie zapytanie:
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
)
Kiedy table1.common_id
nie jest pustych, wszystkie te pytania są semantycznie samo.
Gdy jest pustych, NOT IN
jest inna, ponieważ IN
(a zatem NOT IN
) zwracają NULL
gdy wartość nie pasuje do niczego w wykazie zawierającym NULL
.
To może 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
)
Efektem tego stanu jest wartością logiczną iloczyn wszystkich porównań w obrębie listy. Oczywiście, pojedyncza wartość NULL
daje wynik NULL
, który również oddaje cały wynik NULL
.
Nigdy nie możemy powiedzieć jednoznacznie, że common_id
nie jest równe cokolwiek z tej listy, ponieważ przynajmniej jedna z wartości to NULL
.
Załóżmy, że mamy następujące dane:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN/IS NULL
i NOT EXISTS
powróci 3
, NOT IN
powróci nic (ponieważ zawsze będzie oceniać albo FALSE
lub NULL
).
W MySQL
w przypadku na niż wartości pustych kolumnie LEFT JOIN/IS NULL
i NOT IN
są trochę (kilka procent) bardziej skuteczny niż NOT EXISTS
. Jeśli kolumna jest zerowa, najbardziej efektywna jest wersja NOT EXISTS
(znowu niewiele).
W przypadku wszystkich trzech zapytań są wyświetlane te same plany (ANTI JOIN
).
W SQL Server
, NOT IN
/NOT EXISTS
są bardziej skuteczne, gdyż LEFT JOIN/IS NULL
nie mogą być optymalizowane do ANTI JOIN
jego Optimizer.
W PostgreSQL
, LEFT JOIN/IS NULL
i NOT EXISTS
są bardziej skuteczne niż NOT IN
sinus są zoptymalizowane do Anti Join
, a NOT IN
wykorzystuje hashed subplan
(lub nawet gładkie subplan
jeśli podkwerendę jest zbyt duża, aby hash)
To https://stackoverflow.com/a/129152/1667619 odpowiada na pytanie DLACZEGO całkiem dobrze. – Ruchan