Correcto uso de un indice compuesto

06/07/2004 - 23:09 por A. Borga | Informe spam
Tengo una tabla de aprox 200 mil registros el cual tiene 1 indice compuesto
de 2 columnas (coddoc,nrodoc). Ahora mi duda es la siguiente:

1) SELECT * FROM facturas WHERE coddoc+nroddoc = '01005-000005'

2) SELECT * FROM facturas WHERE coddoc = '01' And nroddoc = '005-000005'

Hasta la fecha e estado utilizando la forma (1), pero por probar y tratar de
agilizar una consulta utilice la opcion (2) y realmente quede sorprendido ya
que arroja el resultado mucho mas rapido que el primero. la pregunta es ¿En
indices compuestos cual es el correcto uso?
 

Leer las respuestas

#1 Emilio Boucau \(en casa\)
07/07/2004 - 01:43 | Informe spam
Hola,

la primera parte a tu respuesta es: en índices (compuestos o no) usar Campo
COMPARACION Valor y concatenar con ANDs y ORs.

la segunda parte de la respuesta es que en la primera no hace uso del índice
y en la segunda sí. Por que ? Porque si bein tenes un índice compuesto se
debe usar evaluando cada componente del índice por separado; es decir,
pedirle que ubique la fila cuyos valores sean coddoc = '01' y nroddoc '005-000005'. Si buscas como la forma (1), hara un barrido fila a fila DE
TODA LA TABLA concatenando ambas columnas y luego comparándola contra la
cadena '01005-000005' y no se detendra hasata el final. Si puede usar un
índice, accede directo a la fila/s que necesita y sabe precisamente cuando
debe terminar.

Es más, si pones condiciones unidas por AND y OR y SQL Server tiene índices
que soporten cada 'partecita' de la consulta, lanzará búsquedas simultáneas
en las tablas y luego las unirá con Merge Joins, Hash Joins y otros tipos de
Joins propios (no confundir con los JOINs que podes hacer en la tablas tipo
INNER, LEFT, etc.). Un ejemplo de lo que te menciono es el siguiente:
digamos que tenes un índice por coddoc y otro por nroddoc (simples, no
compuestos) y haces una búsqueda del tipo WHERE coddoc = '01' OR nroddoc '005-000005' (aunque no sea tu caso), SQL Server recuperará todas las que
cumplan la primer a condicion del índice correspondiete y las que cumplan la
segunda condición de su índice correspondiete; luego, las 'pega' y te las
deveulve todas juntas.
Si tu consulta fuera WHERE coddoc = '01' AND nroddoc = '005-000005', hará lo
mismo para recuperar las fila pero antes de 'pegarla' y devolveras validará
la condicion total.

Como reglas de oro para que optimices tus consultas
por más que tengas definido un índice, SQL Server no lo podrá usar si buscas
asi:

1) resultantes de cálculos o funciones: se resuleven en tiempo de ejecución
y no se pueden acceder directamente porque no hay un índice que tenga ese
valor almacendao (porque es el valor de verdad de una comparacion: dara True
o False)
Ejemplos:
WHERE coddoc+nroddoc = '01005-000005'
WHERE DatePart( mm, Columna_Fecha ) = 6
WHERE Upper( Columna ) = 'EMILIO'

2) incluyen operador NOT o <> : debera barrer CADA FILA para saber si es
distinta o no.
WHERE Campo <> 0

mucho mejor sería usar WHERE Campo > 0 AND Campo < 0 ya que puede tomar del
índice los valores necesarios.

Te recomiendo que te familiarices con el Plande Ejecución / Query Plan y
veas realemnte que hace el motor. No te será sencillo al principio ya que no
es muy 'amigable' que digamos pero con el uso le tomarás la mano y veras lo
útil que es. El correcto uso de los índices y los argumentos de búsqueda
(SARGs) da para largo. Perdón por hacerlo tan largo ...


Saludos !

Emilio Boucau
Buenos Aires - Argentina
http://www.portalsql.com

Preguntas similares