Mejora de rendimiento de NOT EXISTS vs NOT IN

09.01.2014 17:56

El uso de la instrucción  NOT IN  suele ser mas frecuente que el de NOT EXISTS. Aunque a simple vista pueden parecer equivalentes no es asi en muchas ocasiones. Veamos un ejemplo:

 

Tenemos 2 querys que dan los mismos resultados utilizando ambas instrucciones sobre la base de datos AdventureWorksDW2012:

 

SELECT *
  FROM [AdventureWorksDW2012].[dbo].[DimCustomer] where GeographyKey  not in (select GeographyKey from  [dbo].[DimGeography] where [GeographyKey]> 10)
 

y

SELECT *
  FROM [AdventureWorksDW2012].[dbo].[DimCustomer] as c where   not exists (select GeographyKey from [AdventureWorksDW2012].[dbo].[DimGeography] as g  where (c.GeographyKey =g.GeographyKey and g.GeographyKey >10))

 

Veamos el plan de ejecucion de la primera:

 

Aqui vemos que se ejecuta un Row Count Spool con un coste del 56% mientras que esto desaparece totalmente en el caso de NOT EXISTS

Por último los tiempos de ejecución en el primer caso ( NOT IN) son de :

Tiempo de análisis y compilación de SQL Server:
   Tiempo de CPU = 0 ms, tiempo transcurrido = 289 ms.

y para NOT EXISTS


Tiempo de análisis y compilación de SQL Server:
   Tiempo de CPU = 16 ms, tiempo transcurrido = 436 ms.

 

Aunque en  este caso no se pueden hablar de diferencias muy significativas, esto cambia radicalmente en el caso de que el campo admita NULL

siendo la diferencia muchísimo mas favorable en rendimiento a NOT EXISTS