Actualizar:
Estos artículos en mi blog describen las diferencias entre los métodos con más detalle:
Hay tres formas de hacer una consulta de este tipo:
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
)
Cuando table1.common_idno es anulable, todas estas consultas son semánticamente iguales.
Cuando es anulable, NOT INes diferente, ya que IN(y, por lo tanto NOT IN) regresa NULLcuando un valor no coincide con nada en una lista que contiene un NULL.
Esto puede ser confuso pero puede volverse más obvio si recordamos la sintaxis alternativa para esto:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
El resultado de esta condición es un producto booleano de todas las comparaciones dentro de la lista. Por supuesto, un solo NULLvalor produce el NULLresultado que también representa el resultado completo NULL.
Nunca podemos decir definitivamente que common_idno es igual a nada de esta lista, ya que al menos uno de los valores lo es NULL.
Supongamos que tenemos estos datos:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN / IS NULLy NOT EXISTSvolverá 3, NOT INvolverá nada (ya que siempre evaluará a cualquiera FALSEo NULL).
En MySQL, en el caso de la columna no anulable, LEFT JOIN / IS NULLy NOT INson un poco (varios por ciento) más eficientes que NOT EXISTS. Si la columna es anulable, NOT EXISTSes la más eficiente (nuevamente, no mucho).
En Oracle, las tres consultas producen los mismos planes (an ANTI JOIN).
En SQL Server, NOT IN/ NOT EXISTSson más eficientes, ya LEFT JOIN / IS NULLque no puede ser optimizado para un ANTI JOINpor su optimizador.
En PostgreSQL, LEFT JOIN / IS NULLy NOT EXISTSson más eficientes que NOT IN, sinusoidales, están optimizados para un Anti Join, mientras que los NOT INusos hashed subplan(o incluso un plano subplansi la subconsulta es demasiado grande para el hash)