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

#11 Alejandro Mesa
12/05/2005 - 14:14 | Informe spam
Correccion,

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,



De la primera y del conjunto en su totalidad, o sea si el indice es (c1,
c2), entonces sql server mantiene estadisticas para c1 y (c1, c2), pero no
para c2 como podemos verlo cuado ejecutamos el comand DBCC SHOW_STATISTICS.


AMB

"Alejandro Mesa" wrote:

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
#12 Maxi
12/05/2005 - 15:54 | Informe spam
No coincido con eso, no es lo mismo un indice por columna que indices
combinados.

Podriar probarlo de forma simple:

Te creas indices combinados por 2 columnas (campos1,campo2) y haces esto

Select campo1,campo2 from tabla where campo1 = 'pepe'


Respeta el orden y proba , mirate los planes de ejecucion y nos contas ;)

Salu2
Maxi


"Danilsa" escribió en el mensaje
news:eYJV%
> 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
#13 Luis Nivar
12/05/2005 - 15:56 | Informe spam
Mira uno aprende muchas cosas en este foro.

Una preguntica:

Para el caso que se planteo, como dices solo basta que definan dos indices,
uno por campo codigo y otro por campo fecha pues sql server se encarga de
usarlos apropiadamente en consultas compuestas. Pero mi inquietud entonces,
es que en que situacion es que es realmente necesario definir un indice
compuesto ?

O no son realmente necesarios nunca, a menos que sean claves primarias o
foraneas ?




"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
#14 Alejandro Mesa
12/05/2005 - 17:20 | Informe spam
Maxi,

Ese es un caso especial que no tuve tiempo de tocar en el mensaje de ayer.
Este tipo de indice se les conoce como "covering" debido a que todas las
columnas referenciadas en la sentencia select (las que estan en la lista de
columnas, en la clausula where, en la clausula group by, etc.) son incluidas
en el indice. Este tipo de indice siempre suele ser un nonclustered y es muy
util debido a que sql server no necesita hacer la doble lectura (Bookmark
Lookup) del indice nonclustered y el indice clustered o la tabla en caso de
que esta sea un heap (tabla sin indice clustered). Tenemos el caso de que un
indice con una sola columna puede ser tambien un indice "covering" si la
tabla contiene un indice clustered y la sentencia select solo referencia la
columna usada por el indice nonclustered y las columnas que participan en la
llave del indice clustered, esto de debe a que los indices nonclustered hacen
referencia a las llaves de los indices clustered.

Ejemplo:

use northwind
go

exec sp_helpindex 'dbo.orders'
go

set showplan_text on
go

select orderid, orderdate
from dbo.orders
where orderdate >= '19980101' and orderdate < '19980701'
go

set showplan_text off
go

Como resultado de ejecutar sp_helpindex 'dbo.orders', veras que la tabla
[dbo].[orders] tiene un indice clustered "PK_Orders" cuya llave es "OrderID"
y tambien tiene un indice nonclustered "OrderDate" cuya llave es "OrderDate".
En el plan de ejecucion se ve que sql server hace un seek en el indice
"OrderDate" pero no hace uso del operador "Bookmark Lookup" y eso se debe a
que el indice "OrderDate" contiene el valor de la columna "OrderID" porque
esta es la llave del indice clustered. Tan pronto como incluimos una columna
mas en la sentencia select, sql server deja de usar ese indice.

set showplan_text on
go

select orderid, orderdate, customerid
from dbo.orders
where orderdate >= '19980101' and orderdate < '19980701'
go

set showplan_text off
go

En el mensaje de ayer comente varias veces que sql server hace un uso
especial con estos indices. Yo no usaria estos indices como un ejemplo usual
respecto al uso de indices en sql server, ademas recuerda que mientras mas
ancha sea la llave de un indice, mas operaciones de actualizacion tendra que
hacer sql server.


AMB

"Maxi" wrote:

No coincido con eso, no es lo mismo un indice por columna que indices
combinados.

Podriar probarlo de forma simple:

Te creas indices combinados por 2 columnas (campos1,campo2) y haces esto

Select campo1,campo2 from tabla where campo1 = 'pepe'


Respeta el orden y proba , mirate los planes de ejecucion y nos contas ;)

Salu2
Maxi


"Danilsa" escribió en el mensaje
news:eYJV%
>> > 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
#15 Alejandro Mesa
12/05/2005 - 17:28 | Informe spam
Luis,

O no son realmente necesarios nunca, a menos que sean claves primarias o
foraneas ?



No seamos tan estrictos. Por ejemplo, cuando la selectividad de una sola
columna no es buena o baja, añadiendo otra columna a la llave puede mejorarla
mucho y si usamos sentencias select que a menudo filtran por ambas (pueden
ser 3, 4 etc con un limite de 16 columnas) entonces el uso de una llave
compuesta para un indice biene de maravillas.


AMB

"Luis Nivar" wrote:

Mira uno aprende muchas cosas en este foro.

Una preguntica:

Para el caso que se planteo, como dices solo basta que definan dos indices,
uno por campo codigo y otro por campo fecha pues sql server se encarga de
usarlos apropiadamente en consultas compuestas. Pero mi inquietud entonces,
es que en que situacion es que es realmente necesario definir un indice
compuesto ?

O no son realmente necesarios nunca, a menos que sean claves primarias o
foraneas ?




"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