Indices cuales ?

11/05/2005 - 17:47 por Tamara | Informe spam
Si yo tengo un campo fecha y otro codigo en una tabla y suelo hacer
busquedas frecuentes tango por codigo como por fecha como por codigo+fecha
como por fecha+codigo, se supone que deberia tener un indice para cada caso,
es decir 4 indices ?

Preguntas similare

Leer las respuestas

#6 Alejandro Mesa
11/05/2005 - 22:59 | Informe spam
Maxi,

> Te refieres al orden en que se enumeran las columns en el create index o
> al
> orden en que se especifican en la clausula WHERE de un select ?

Ambos, no es lo mismo un indice Fecha,codigo que luego se consulte asi que
uno Codigo,Fecha



Tiene mucha importancia el orden en el que se especifican las columnas
cuando creamos el indice, pero no tiene ningun efecto el order en que
aparecen las columnas en la clausula WHERE, pues sql server no escoge el plan
de ejecucion basado en eso. Es mas, no existe un order de evaluacion
predeterminado para evaluar las expresiones que aparecen en una clausula
WHERE.

Te exorto a que leas este hilo, en el cual Gert-Jan Strik expone un buen
ejemplo.

http://support.microsoft.com/newsgr...ng&midˆb5174e-5980-4d7d-8a9d-3e1d7604418a&sloc=en-us&sloc=en-us


AMB

"Maxi" wrote:

Hola, articulos hay muchos, podrias ir a www.mug.org.ar y encontraras
algunos.

> Te refieres al orden en que se enumeran las columns en el create index o
> al
> orden en que se especifican en la clausula WHERE de un select ?

Ambos, no es lo mismo un indice Fecha,codigo que luego se consulte asi que
uno Codigo,Fecha

> Que ocurriria cuando se hagan consultas solo por fecha o solo por codigo ?
> No se verian afectadas en rendimiento ?
>

Usara los indices (en teoria)

> Por que es tan contradictoria esta opinion con la del otro companero de
> arriba ?

Que es lo que ves contradictorio?

Salu2
Maxi


"Danilsa" escribió en el mensaje
news:
> Hola,
> Me interesa muchiiiisimo tambien este tema. He buscado y no encuentro
> escritos que ayuden a uno a mentalizar cuales son los mejores indices para
> una tabla.
>
>> Hola, a ver, el orden es importante en los indices, si haces busquedas
>> fecha,codigo y luego codigo,fecha podes hacer una cosa
>>
> Te refieres al orden en que se enumeran las columns en el create index o
> al
> orden en que se especifican en la clausula WHERE de un select ?
>
>> 1) sistematizar para que todas sean de una sola manera
>> 2) Armar 2 juegos de indices
>>
>
> fecha,codigo y codigo,fecha
>
> Que ocurriria cuando se hagan consultas solo por fecha o solo por codigo ?
> No se verian afectadas en rendimiento ?
>
> Por que es tan contradictoria esta opinion con la del otro companero de
> arriba ?
>
> Conocen algun articulo que me ayude a aclarar este concepto?
>
> graciasssss...
>
>



Respuesta Responder a este mensaje
#7 Maxi
12/05/2005 - 00:48 | Informe spam
Tienes razon, me confundo con el orden que se ponen en el select y no en el
Where :(


Maxi - Buenos Aires - Argentina
Desarrollador 3 Estrellas
Msn:

Maxi.da[arroba]gmail.com

"Alejandro Mesa" escribió en el
mensaje news:
Maxi,

> Te refieres al orden en que se enumeran las columns en el create index
> o
> al
> orden en que se especifican en la clausula WHERE de un select ?

Ambos, no es lo mismo un indice Fecha,codigo que luego se consulte asi
que
uno Codigo,Fecha



Tiene mucha importancia el orden en el que se especifican las columnas
cuando creamos el indice, pero no tiene ningun efecto el order en que
aparecen las columnas en la clausula WHERE, pues sql server no escoge el
plan
de ejecucion basado en eso. Es mas, no existe un order de evaluacion
predeterminado para evaluar las expresiones que aparecen en una clausula
WHERE.

Te exorto a que leas este hilo, en el cual Gert-Jan Strik expone un buen
ejemplo.

http://support.microsoft.com/newsgr...ng&midˆb5174e-5980-4d7d-8a9d-3e1d7604418a&sloc=en-us&sloc=en-us


AMB

"Maxi" wrote:

Hola, articulos hay muchos, podrias ir a www.mug.org.ar y encontraras
algunos.

> Te refieres al orden en que se enumeran las columns en el create index
> o
> al
> orden en que se especifican en la clausula WHERE de un select ?

Ambos, no es lo mismo un indice Fecha,codigo que luego se consulte asi
que
uno Codigo,Fecha

> Que ocurriria cuando se hagan consultas solo por fecha o solo por
> codigo ?
> No se verian afectadas en rendimiento ?
>

Usara los indices (en teoria)

> Por que es tan contradictoria esta opinion con la del otro companero de
> arriba ?

Que es lo que ves contradictorio?

Salu2
Maxi


"Danilsa" escribió en el mensaje
news:
> Hola,
> Me interesa muchiiiisimo tambien este tema. He buscado y no encuentro
> escritos que ayuden a uno a mentalizar cuales son los mejores indices
> para
> una tabla.
>
>> Hola, a ver, el orden es importante en los indices, si haces busquedas
>> fecha,codigo y luego codigo,fecha podes hacer una cosa
>>
> Te refieres al orden en que se enumeran las columns en el create index
> o
> al
> orden en que se especifican en la clausula WHERE de un select ?
>
>> 1) sistematizar para que todas sean de una sola manera
>> 2) Armar 2 juegos de indices
>>
>
> fecha,codigo y codigo,fecha
>
> Que ocurriria cuando se hagan consultas solo por fecha o solo por
> codigo ?
> No se verian afectadas en rendimiento ?
>
> Por que es tan contradictoria esta opinion con la del otro companero de
> arriba ?
>
> Conocen algun articulo que me ayude a aclarar este concepto?
>
> graciasssss...
>
>



Respuesta Responder a este mensaje
#8 Ricardo Passians
12/05/2005 - 04:01 | Informe spam
Es la explicación de todo un maestro. Te felicito, Alejandro. Si pudieras y
prepararas un artículo con ese tema.

Saludos.


"Alejandro Mesa" wrote in message
news:
Danilsa,

> > Hola, a ver, el orden es importante en los indices, si haces busquedas
> > fecha,codigo y luego codigo,fecha podes hacer una cosa
> >
> Te refieres al orden en que se enumeran las columns en el create index o


al
> orden en que se especifican en la clausula WHERE de un select ?

Es importante el orden en el que se especifican las columnas cuando creas


el
indice.

SQL Server solo guarda solo las estadisticas de la primera columna de un
indice compuesto (indices multi-columnas), por lo que si tu indice es (c1,
c2) sql server podra hacer un seek en el indice si en la clausula "where"
usas c1 = ? and c2 = ? o c1 = ?, pero hara un scan del indice / tabla si


solo
aparece c2 = ?.

Ejemplo:

use northwind
go

select
orderid,
customerid,
orderdate
into
dbo.t1
from
dbo.orders
go

create nonclustered index ix_nc_t1_customerid_orderdate on
dbo.t1(customerid, orderdate)
go

set showplan_text on
go

select
orderid,
customerid,
orderdate
from
dbo.t1
where
customerid = 'alfki'
and orderdate = '19970825'
go

select
orderid,
customerid,
orderdate
from
dbo.t1
where
customerid = 'alfki'
go

select
orderid,
customerid,
orderdate
from
dbo.t1
where
orderdate = '19970825'
go

set showplan_text off
go

drop table dbo.t1
go

Otra cosa importante es que si la selectividad en la primera columna es


baja
(dado un valor de la columna se seleccionaran muchas filas), entonces


cuando
se hace una consulta por c1 = ?, sql server preferira hacer un scan de la
tabla o usar otro indice porque cuando se lee un indice nonclustered


(excepto
cuando el indice cubre todas las columnas referenciadas en la sentencia
select) luego hay que leer el indice clustered si este existe o la tabla,


o
sea se hace una lectura doble y esto se ve en el plan de ejecucion con el
operador Bookmark Lookup. Fijate en el texto del plan de ejecucion del
ejemplo para que veas que despues de hacer el "index seek" y encontrar la
llave del indice, sql server hace despues un Bookmark Lookup.

Para ver la selectividad puedes usar el comando DBCC SHOW_STATISTICS
(nombre_tabla, nombre indice) y fijate en el resultado del segundo set o
conjunto, especificamente el que dice "All density". La densidad indica el
porciento de valores duplicados bajo las columnas especificadas en


"Columns".
LA selectividad y la densidad son inversas, esto significa que menor


densidad
mayor selectividad y mayor densidad menor selectividad.

Ejemplo:

select
orderid,
productid,
unitprice,
quantity,
discount
into
dbo.t1
from
dbo.[order details]
go

create nonclustered index ix_nc_t1_productid_orderid on dbo.t1(productid,
orderid)
go

DBCC SHOW_STATISTICS ('dbo.t1', 'ix_nc_t1_productid_orderid')
go

set showplan_text on
go

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
productid = 59
and orderid = 10387
go

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
productid = 59
go

set showplan_text off
go

drop table dbo.t1
go

Fijate que la densidad para la columna [productid] es 1.2987013E-2 y para


la
combinacion (productid, orderid) es 4.6403712E-4. Esto nos dice que la
selectividad por [productid] es mucho menor (fijate que los numeros estan
expresados en notacion exponencial) que la selectividad por ambas y este


caso
si hacemos un filtro por [productid] = ? hara que sql server haga un scan


de
la tabla, pero si el filtro es [productid] = ? and [orderid] = ? entonces
hara un seek. que pasa si cambiamos el orden de las columnas en el


indice?,
veamos:

drop index dbo.t1.ix_nc_t1_productid_orderid
go

create nonclustered index ix_nc_t1_orderid_productid on dbo.t1(orderid,
productid)
go

DBCC SHOW_STATISTICS ('dbo.t1', 'ix_nc_t1_orderid_productid')
go

set showplan_text on
go

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
orderid = 10387
and productid = 59
go

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
orderid = 10387
go

set showplan_text off
go

Ahora la densidad por [orderid] es 1.2048193E-3 y por ([orderid],
[productid]) es 4.6403712E-4. Por lo que podemos ver la densidad por
[orderid] es menor que por [productid] (1.2048193E-3 vs 1.2987013E-2) pero
aun no es menor que la combinacion, pero un buen valor para que sql server
haga un seek en el indice cuando usamos un filtro como [orderid] = 10387.

Lo ultimo ahora es decir que se usa mucho los indices multi-columnas para
mejorar la selectividad (excepto en indices multi-columnas que cubren


todas
columnas referenciadas en la sentencia select). Esto se puede evitar si
descompnemos el indice multicolumna en dos indices sencillos (no siempre


es
asi), puesto que sql server es lo suficiente inteligente para usar ambos
indices en conjunto.

Ejemplo:

drop index dbo.t1.ix_nc_t1_orderid_productid
go

create nonclustered index ix_nc_t1_orderid on dbo.t1(orderid)
go

create nonclustered index ix_nc_t1_productid on dbo.t1(productid)
go

set showplan_text on
go

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
orderid = 10387
and productid = 59
go

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
orderid = 10387

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
productid = 59
go

set showplan_text off
go

drop table dbo.t1
go

fijate que sql server have un seek en el indice cuando el filtro es
[orderid] = ? o [orderid] = ? and [productid] = ?. Hace un scan de la


tabla
cuando el filtro es [productid] = ? debido, como habiamos dicho, a que la
densidad por [productis] es muy alta.

Espero y esto te ayude a entender un poco mejor los indices, sobre todo


los
nonclustered. Aca te paso unos links donde puedes leer al respecto.

Not All SQL Server Indexes Are Created Equal
http://www.sql-server-performance.c..._equal.asp

en este link, bajo este encabezado " Find SQL Server Performance Tips by
Category
", busca Indexes(General, Clustered, Composite, Covering y
Non-clustered)http://www.sql-server-performance.com/default.asp


AMB

"Danilsa" wrote:

> Hola,
> Me interesa muchiiiisimo tambien este tema. He buscado y no encuentro
> escritos que ayuden a uno a mentalizar cuales son los mejores indices


para
> una tabla.
>
> > Hola, a ver, el orden es importante en los indices, si haces busquedas
> > fecha,codigo y luego codigo,fecha podes hacer una cosa
> >
> Te refieres al orden en que se enumeran las columns en el create index o


al
> orden en que se especifican en la clausula WHERE de un select ?
>
> > 1) sistematizar para que todas sean de una sola manera
> > 2) Armar 2 juegos de indices
> >
>
> fecha,codigo y codigo,fecha
>
> Que ocurriria cuando se hagan consultas solo por fecha o solo por codigo


?
> No se verian afectadas en rendimiento ?
>
> Por que es tan contradictoria esta opinion con la del otro companero de
> arriba ?
>
> Conocen algun articulo que me ayude a aclarar este concepto?
>
> graciasssss...
>
>
>
Respuesta Responder a este mensaje
#9 Danilsa
12/05/2005 - 11:43 | Informe spam
> Por que es tan contradictoria esta opinion con la del otro companero de
> arriba ?

Que es lo que ves contradictorio?



Que Alejandro sustenta que basta con tener un indice independiente por cada
columna, esto es, sin combinarlos.
Respuesta Responder a este mensaje
#10 Danilsa
12/05/2005 - 11:44 | Informe spam
Muchas gracias.
Me ha ayudado bastante.

"Alejandro Mesa" wrote in message
news:
Danilsa,

> > Hola, a ver, el orden es importante en los indices, si haces busquedas
> > fecha,codigo y luego codigo,fecha podes hacer una cosa
> >
> Te refieres al orden en que se enumeran las columns en el create index o


al
> orden en que se especifican en la clausula WHERE de un select ?

Es importante el orden en el que se especifican las columnas cuando creas


el
indice.

SQL Server solo guarda solo las estadisticas de la primera columna de un
indice compuesto (indices multi-columnas), por lo que si tu indice es (c1,
c2) sql server podra hacer un seek en el indice si en la clausula "where"
usas c1 = ? and c2 = ? o c1 = ?, pero hara un scan del indice / tabla si


solo
aparece c2 = ?.

Ejemplo:

use northwind
go

select
orderid,
customerid,
orderdate
into
dbo.t1
from
dbo.orders
go

create nonclustered index ix_nc_t1_customerid_orderdate on
dbo.t1(customerid, orderdate)
go

set showplan_text on
go

select
orderid,
customerid,
orderdate
from
dbo.t1
where
customerid = 'alfki'
and orderdate = '19970825'
go

select
orderid,
customerid,
orderdate
from
dbo.t1
where
customerid = 'alfki'
go

select
orderid,
customerid,
orderdate
from
dbo.t1
where
orderdate = '19970825'
go

set showplan_text off
go

drop table dbo.t1
go

Otra cosa importante es que si la selectividad en la primera columna es


baja
(dado un valor de la columna se seleccionaran muchas filas), entonces


cuando
se hace una consulta por c1 = ?, sql server preferira hacer un scan de la
tabla o usar otro indice porque cuando se lee un indice nonclustered


(excepto
cuando el indice cubre todas las columnas referenciadas en la sentencia
select) luego hay que leer el indice clustered si este existe o la tabla,


o
sea se hace una lectura doble y esto se ve en el plan de ejecucion con el
operador Bookmark Lookup. Fijate en el texto del plan de ejecucion del
ejemplo para que veas que despues de hacer el "index seek" y encontrar la
llave del indice, sql server hace despues un Bookmark Lookup.

Para ver la selectividad puedes usar el comando DBCC SHOW_STATISTICS
(nombre_tabla, nombre indice) y fijate en el resultado del segundo set o
conjunto, especificamente el que dice "All density". La densidad indica el
porciento de valores duplicados bajo las columnas especificadas en


"Columns".
LA selectividad y la densidad son inversas, esto significa que menor


densidad
mayor selectividad y mayor densidad menor selectividad.

Ejemplo:

select
orderid,
productid,
unitprice,
quantity,
discount
into
dbo.t1
from
dbo.[order details]
go

create nonclustered index ix_nc_t1_productid_orderid on dbo.t1(productid,
orderid)
go

DBCC SHOW_STATISTICS ('dbo.t1', 'ix_nc_t1_productid_orderid')
go

set showplan_text on
go

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
productid = 59
and orderid = 10387
go

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
productid = 59
go

set showplan_text off
go

drop table dbo.t1
go

Fijate que la densidad para la columna [productid] es 1.2987013E-2 y para


la
combinacion (productid, orderid) es 4.6403712E-4. Esto nos dice que la
selectividad por [productid] es mucho menor (fijate que los numeros estan
expresados en notacion exponencial) que la selectividad por ambas y este


caso
si hacemos un filtro por [productid] = ? hara que sql server haga un scan


de
la tabla, pero si el filtro es [productid] = ? and [orderid] = ? entonces
hara un seek. que pasa si cambiamos el orden de las columnas en el


indice?,
veamos:

drop index dbo.t1.ix_nc_t1_productid_orderid
go

create nonclustered index ix_nc_t1_orderid_productid on dbo.t1(orderid,
productid)
go

DBCC SHOW_STATISTICS ('dbo.t1', 'ix_nc_t1_orderid_productid')
go

set showplan_text on
go

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
orderid = 10387
and productid = 59
go

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
orderid = 10387
go

set showplan_text off
go

Ahora la densidad por [orderid] es 1.2048193E-3 y por ([orderid],
[productid]) es 4.6403712E-4. Por lo que podemos ver la densidad por
[orderid] es menor que por [productid] (1.2048193E-3 vs 1.2987013E-2) pero
aun no es menor que la combinacion, pero un buen valor para que sql server
haga un seek en el indice cuando usamos un filtro como [orderid] = 10387.

Lo ultimo ahora es decir que se usa mucho los indices multi-columnas para
mejorar la selectividad (excepto en indices multi-columnas que cubren


todas
columnas referenciadas en la sentencia select). Esto se puede evitar si
descompnemos el indice multicolumna en dos indices sencillos (no siempre


es
asi), puesto que sql server es lo suficiente inteligente para usar ambos
indices en conjunto.

Ejemplo:

drop index dbo.t1.ix_nc_t1_orderid_productid
go

create nonclustered index ix_nc_t1_orderid on dbo.t1(orderid)
go

create nonclustered index ix_nc_t1_productid on dbo.t1(productid)
go

set showplan_text on
go

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
orderid = 10387
and productid = 59
go

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
orderid = 10387

select
orderid,
productid,
unitprice,
quantity,
discount
from
dbo.t1
where
productid = 59
go

set showplan_text off
go

drop table dbo.t1
go

fijate que sql server have un seek en el indice cuando el filtro es
[orderid] = ? o [orderid] = ? and [productid] = ?. Hace un scan de la


tabla
cuando el filtro es [productid] = ? debido, como habiamos dicho, a que la
densidad por [productis] es muy alta.

Espero y esto te ayude a entender un poco mejor los indices, sobre todo


los
nonclustered. Aca te paso unos links donde puedes leer al respecto.

Not All SQL Server Indexes Are Created Equal
http://www.sql-server-performance.c..._equal.asp

en este link, bajo este encabezado " Find SQL Server Performance Tips by
Category
", busca Indexes(General, Clustered, Composite, Covering y
Non-clustered)http://www.sql-server-performance.com/default.asp


AMB

"Danilsa" wrote:

> Hola,
> Me interesa muchiiiisimo tambien este tema. He buscado y no encuentro
> escritos que ayuden a uno a mentalizar cuales son los mejores indices


para
> una tabla.
>
> > Hola, a ver, el orden es importante en los indices, si haces busquedas
> > fecha,codigo y luego codigo,fecha podes hacer una cosa
> >
> Te refieres al orden en que se enumeran las columns en el create index o


al
> orden en que se especifican en la clausula WHERE de un select ?
>
> > 1) sistematizar para que todas sean de una sola manera
> > 2) Armar 2 juegos de indices
> >
>
> fecha,codigo y codigo,fecha
>
> Que ocurriria cuando se hagan consultas solo por fecha o solo por codigo


?
> No se verian afectadas en rendimiento ?
>
> Por que es tan contradictoria esta opinion con la del otro companero de
> arriba ?
>
> Conocen algun articulo que me ayude a aclarar este concepto?
>
> graciasssss...
>
>
>
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida