Actualización:
Estos artículos en mi blog describen las diferencias entre los métodos más detalle:
Hay tres maneras de hacer este tipo de consulta:
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_id
no es anulable, todas estas consultas son semánticamente el mismo.
Cuando es anulable, NOT IN
es diferente, ya que IN
(y, por lo tanto, NOT IN
) volver NULL
cuando un valor no coincide con cualquier cosa en una lista que contiene una NULL
.
Esto puede ser confuso, pero puede llegar a ser más evidente 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 único valor NULL
produce el resultado NULL
que representa el resultado completo NULL
también.
Nunca podemos decir definitivamente que common_id
no es igual a nada de esta lista, ya que al menos uno de los valores es NULL
.
Supongamos que tenemos estos datos:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN/IS NULL
y NOT EXISTS
volverá 3
, NOT IN
volverá nada (ya que siempre se evaluará como sea FALSE
o NULL
).
En MySQL
, en caso de que en la columna no anulable, LEFT JOIN/IS NULL
y NOT IN
son un poco (varios por ciento) más eficiente que NOT EXISTS
. Si la columna es nulable, NOT EXISTS
es la más eficiente (nuevamente, no mucho).
En Oracle
, las tres consultas producen los mismos planes (un ANTI JOIN
).
En SQL Server
, NOT IN
/NOT EXISTS
son más eficientes, ya que LEFT JOIN/IS NULL
no puede ser optimizado para un ANTI JOIN
por su optimizador.
En PostgreSQL
, LEFT JOIN/IS NULL
y NOT EXISTS
son más eficientes que NOT IN
, sine que están optimizados para un Anti Join
, mientras NOT IN
utiliza hashed subplan
(o incluso una llanura subplan
si la subconsulta es demasiado grande para hash)
Este https://stackoverflow.com/a/129152/1667619 responde bastante bien a la pregunta WHY. – Ruchan