Introducción
En este artículo se van a mostrar algunas diferencias que existen entre los operadores INNER JOIN y NOT IN o IN. Cuando usamos estos recursos, por lo general queremos obtener resultados que necesitan filtrar dos o más tablas, pero nos podemos encontrar con algunos inconvenientes.
Para llevar a cabo el ejemplo, utilizaremos datos de personas que han comprado algún producto en alguno de los destinos que tenemos registrados.
Tablas y datos con los que haremos pruebas:
Supongamos que queremos saber la cantidad de dinero total que han gastado en productos los compradores, pero solo de aquellos que no han visitado algunos de los destinos que tenemos registrados. Para ello vamos a usar el operador NOT IN:
Como se puede comprobar no saca ningún resultado y esto es debido al NULL que aparece en nuestra tabla “destinos”.
Ahora comprobaremos el gasto total de los compradores, pero esta vez de aquellos que compraron en los destinos que tenemos registrados. Esta consulta se podría llevar a cabo con un IN pero vamos a usar INNER JOIN ya que es más rápido y eficiente:
Si observamos el resultado, se ha duplicado el gasto total del comprador 3 (debería ser 75). Esto es debido a que la INNER JOIN se ha hecho sobre una tabla cuyo campo no era único.
Para evitar este tipo de errores, se va a proponer una solución para los casos tratados anteriormente. Se trata de WHERE EXISTS y se puede aplicar en cualquier situación donde queramos filtrar datos de una consulta con los datos de otras consultas. Observe el siguiente ejemplo donde se quiere sacar los datos de los compradores que no estuvieron en los destinos que tenemos registrados:
Funciona de forma eficaz obteniendo el resultado esperado.
Por último, vamos a comprobar aquellos clientes que compraron en algunos de los destinos registrados y veremos que se obtiene el resultado correcto:
Si observamos el resultado, los datos que han sido arrojados son los correctos.
Hasta el momento se ha estudiado el comportamiento de los distintos operadores en distintas situaciones, pero ahora analizaremos otra parte importante como lo es el rendimiento. Para llevar a cabo estas pruebas se utilizarán dos tablas. Una de ellas tiene casi medio millón de registros y otra más de un millón de registros. Se ejecutan sentencias similares a las ya vistas anteriormente y comprobando el plan de ejecución se puede observar lo siguiente:
Con el uso del operador NOT IN se llevan a cabo numerosas tareas que ralentizarán en proceso de obtención de datos.
Usando INNER JOIN las acciones que se llevan a cabo son las mínimas arrojando de esta manera datos de una manera más rápida y eficaz en cuanto a rendimiento.
En caso de usar NOT EXISTS se observa está en un término medio en cuanto al número de tareas que se tienen que ejecutar para obtener resultados.
En resumen
Con la información proporcionada a lo largo de este artículo llegamos a las siguientes conclusiones:
Debemos ser cautos a la hora de elegir un operador para obtener información en caso de desconocer el contenido y la estructura de la tabla por los siguientes motivos:
-
Con el operador IN o NOT IN, si existiera un registro NULL, la consulta no arrojaría ningún resultado.
-
INNER JOIN puede suponer un problema si la consulta se hace sobre un campo que no es único porque se podrían obtener resultados erróneos. Por lo tanto, dependiendo de la situación, llegaremos a recomendar el uso de LEFT JOIN.
-
El operador EXISTS o NOT EXISTS será de gran ayuda en caso de tener dudas a la hora realizar consultas.
En referencia al rendimiento:
-
El operador IN o NOT IN es mucho menos eficiente que los demás operadores vistos anteriormente ya que procesará primero el resultado completo de la subconsulta y luego procesará el resultado de la consulta como un todo.
-
INNER JOIN es el operador más eficiente tal y como se observa en la gráfica visualizada anteriormente.
-
EXISTS devolverá true o false dependiendo de si se han producido coincidencias entre las tablas que se están consultando devolviendo en el resultado las intersecciones.