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

#16 Maxi
12/05/2005 - 17:40 | Informe spam
Sip, totalmente deacuerdo :-)


Salu2
Maxi


"Alejandro Mesa" escribió en el
mensaje news:
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
#17 Alejandro Mesa
12/05/2005 - 17:46 | Informe spam
No existe una regla unica sobre creacion de indices en una base de datos, se
debe hacer un estudio del esquema, de los queries que regularmente se usan y
del nivel de actualizacion de las tablas. Algo que si es recomendable es que
cada tabla tenga in indice clustered y que exista un indice por cada conjunto
de columnas que se usen en restriciones de clave foranea. Que no se usen
columnas con un ancho grande como llave de un indice clustered, pues esta
llave tambien es referenciada por todos los indices nonclusteres
pertenecientes a la tabla, y lo mas importante, que se compruebe el
rendimineto de estos y que la base de datos se monitoree, puesto que un
indice definido hoy puede que no sea practico despues de un año de data
historica.


AMB

"Alejandro Mesa" wrote:

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...
> > >
> > >
> > >
>
>
>
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida