Aggiornare:
Questi articoli nel mio blog descrivono le differenze tra i metodi in modo più dettagliato:
Esistono tre modi per eseguire tale query:
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
)
Quando table1.common_idnon è nullable, tutte queste query sono semanticamente uguali.
Quando è nullable, NOT INè diverso, poiché IN(e, quindi, NOT IN) restituisce NULLquando un valore non corrisponde a nulla in un elenco contenente a NULL.
Questo può essere fonte di confusione ma può diventare più ovvio se ricordiamo la sintassi alternativa per questo:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
Il risultato di questa condizione è un prodotto booleano di tutti i confronti all'interno dell'elenco. Naturalmente, un singolo NULLvalore produce il NULLrisultato che rende anche l'intero risultato NULL.
Non possiamo mai dire con certezza che common_idnon è uguale a niente da questo elenco, poiché almeno uno dei valori è NULL.
Supponiamo di avere questi dati:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN / IS NULLe NOT EXISTSritornerà 3, NOT INnon restituirà nulla (dal momento che valuterà sempre a FALSEo NULL).
In MySQL, nel caso di colonne non annullabili, LEFT JOIN / IS NULLe NOT INsono un po '(diversi percento) più efficienti di NOT EXISTS. Se la colonna è nullable, NOT EXISTSè la più efficiente (di nuovo, non molto).
In Oracle, tutte e tre le query producono gli stessi piani (an ANTI JOIN).
In SQL Server, NOT IN/ NOT EXISTSsono più efficienti, dal momento che LEFT JOIN / IS NULLnon può essere ottimizzato per un ANTI JOINdal suo ottimizzatore.
In PostgreSQL, LEFT JOIN / IS NULLe NOT EXISTSsono più efficienti di NOT IN, sinusoidali sono ottimizzati per un Anti Join, mentre NOT INusi hashed subplan(o anche un semplice subplanse la subquery è troppo grande per l'hash)