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?

Preguntas similare

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
Respuesta Responder a este mensaje
#2 Emilio Boucau \(en casa\)
07/07/2004 - 01:54 | Informe spam
Te recomiendo este site: http://www.sql-server-performance.com


Saludos !

Emilio Boucau
Buenos Aires - Argentina
http://www.portalsql.com
Respuesta Responder a este mensaje
#3 Javier Loria
07/07/2004 - 03:16 | Informe spam
Hola Emilio:
Excelente exposicion, solo un error:
Where Campo<>0 se traduce a WHERE Campo>0 OR Campo<0
Saludos,


Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

Emilio Boucau (en casa) escribio:
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
Respuesta Responder a este mensaje
#4 Víctor
07/07/2004 - 13:42 | Informe spam
Me he quedado de piedra con eso de que es más efectivo "> 0 or < 0" que "<>
0".

En el caso de fechas, ¿"between" ó "> or <"?


"Emilio Boucau (en casa)" escribió en el mensaje
news:%
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


Respuesta Responder a este mensaje
#5 Carlos Sacristan
07/07/2004 - 14:02 | Informe spam
Con tu permiso, Emilio. Por cierto, es agradable verte de nuevo de forma
asidua por aquí :-)

El tema de cómo gestiona SQL Server las búsquedas es muy interesante.
Hay un libro muy bueno (el mejor para mí) que te explica esto (bueno, eso y
mucho más): "A fondo SQL Server 2000", de Kalen Delaney. Te lo recomiendo
totalmente (aunque hay momentos en los que puede llegar a ser bastante
denso, sobre todo si no tienes mucha experiencia)

En cuanto a la segunda pregunta, es lo mismo. Si te fijas en el plan de
ejecución de una consulta que utilice ese operador, verás que traduce el
operador BETWEEN ... AND por >= AND <

Un saludo

-
"Sólo sé que no sé nada. " (Sócrates)

Por favor, responder únicamente al foro
Se agradece la inclusión de sentencias DDL


"Víctor" escribió en el mensaje
news:
Me he quedado de piedra con eso de que es más efectivo "> 0 or < 0" que


"<>
0".

En el caso de fechas, ¿"between" ó "> or <"?


"Emilio Boucau (en casa)" escribió en el mensaje
news:%
> 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
>
>


Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida