Básicamente un predicado  IN es un método abreviado de escribir predicados
concatenados con el operador OR ( especialmente en el caso de usar una lista
de valores). Esto tiene la consecuencia que para pequeñas listas de valores
en ocasiones se llegue a un table scan debido al comportamiento de los
operadores OR.

No quiero complicar las cosas pero también podríamos agregar en la
comparación los  operadores de conjunto EXCEPT e INTERSECT.
No dije que sea malo usar "NOT IN" sino que dije que no es bueno usar "IN"
si hay otras formas de hacerlo, como por ejemplo usando un JOIN.  En
ocasiones los subqueries escritos con IN son cambiados internamente por el
query processor en SQL Server 2000 y en 2005 (pero no en las versiones
anteriores) de forma tal de transformarlos en SEMI JOIN con un distinct, lo
que hace que sea equivalente a escribir una query mas compleja usando JOIN y
por lo tanto lo que dije no es absoluto para todos los casos y debe medirse
en el contexto de cada caso en particular. En las versiones anteriores había
un mecanismo interno de prueba de valores  que hacia más eficiente casi
siempre al  EXISTS que el IN. Bajo ciertas condiciones las sentencias son
equivalentes y en otros casos es mejor un join. En otras ocasiones el
problema de la lógica de tres estados complica las cosas y no siempre se
obtiene el valor que se espera al usar por ejemplo NOT IN pero si se obtiene
al usar NOT EXISTS. El resultado es vacio porque el operador IN es sensible
al tercer estado mientras que el EXISTS no lo es.
En definitiva y para resumir en una frase yo considero que en general es
mejor usar EXISTS que el IN o el NOT EXISTS que el NOT IN, pero
funcionalmente no siempre es lo mismo  y no siempre es mejor en terminos de
rendimiento pero muy dificilmente sea peor.
 En el caso de usar el "NOT" como operador o usar el "<>" se deshabilita el
uso de un índice en casi todos los casos. En SQL 2005 por ejemplo lo prueban
facilmente haciendo consultas como la de abajo en adventure Works y
comparando los costos relativos y los planes.  Es más si se fijan en el plan
dice INDEX SEEK en todos los casos pero lo que termina haciendo en
definitiva es un SCAN que lo pueden ver en el detalle del operador (numero
de filas retornadas por el SEEK).

Select * from Sales.SalesOrderDetail where NOT SalesOrderID = 43659

Select * from Sales.SalesOrderDetail where SalesOrderID <> 43659

Select * from Sales.SalesOrderDetail where SalesOrderID = 43659

Select * from Sales.SalesOrderDetail where NOT SalesOrderID = -1

Select * from Sales.SalesOrderDetail where SalesOrderID <> -1

Select * from Sales.SalesOrderDetail where SalesOrderID = -1

Select * from Sales.SalesOrderDetail where NOT SalesOrderID = 99999999999999

Select * from Sales.SalesOrderDetail where SalesOrderID <> 99999999999999

Select * from Sales.SalesOrderDetail where SalesOrderID = 99999999999999





Select SalesOrderID from Sales.SalesOrderDetail where NOT ProductID = 43659

Select SalesOrderID from Sales.SalesOrderDetail where ProductID <> 43659

Select SalesOrderID from Sales.SalesOrderDetail where ProductID = 43659

Select SalesOrderID from Sales.SalesOrderDetail where NOT ProductID = -1

Select SalesOrderID from Sales.SalesOrderDetail where ProductID <> -1

Select SalesOrderID from Sales.SalesOrderDetail where ProductID = -1

Select SalesOrderID from Sales.SalesOrderDetail where NOT ProductID
=99999999999999

Select SalesOrderID from Sales.SalesOrderDetail where ProductID <>99999999999999

Select SalesOrderID from Sales.SalesOrderDetail where ProductID =99999999999999

-- 
--------------------------------
Atte.
Ing. Jose Mariano Alvarez
SQL Total Consulting






On 8/25/07, Maxi Accotto <[EMAIL PROTECTED]> wrote:
>
> Hola, bueno yo no coincido con lo que dice Mariano, no siempre es malo
> usar not in o in, a mi no me ha pasado que no use los indices por
> ello, pero no digo que no exista un caso donde esto suceda! siempre es
> recomendable igual mirar los planes de ejecucion! pero bueno..
>
> El 24/08/07, PabloC <[EMAIL PROTECTED]> escribió:
> >
> > Gracias Mariano por meterte
> > Ahora bien M A X I....... ayuda!!!!!!
> > Todo lo que escribimos lo tiramos a la basura??
> >
>
>

Responder a