consejo sobre Indices

29/07/2008 - 18:29 por Imac_Man | Informe spam
Hola,

tengo una tabla con los campos codigo, seccion, nombre. tiene una gran
cantidad de registros el codigo es un autonumerico y tiene un indice
clustered, pero la seccion para todos los registro solo pueden ser 6 codigos
diferentes y normalmente las consultas se hacen por medio de la seccion y no
por el codigopor ende las consultas son lentas, como debo hacer los
indices para que esto funcione repido. muchas gracias de antemano

Saludos

Preguntas similare

Leer las respuestas

#1 Gustavo Larriera (MVP)
29/07/2008 - 19:00 | Informe spam
Si bien entiendo que Seccion no es un valor muy selectivo (usted menciona que
solamente hay 6 valores diferentes) intente con un índice adicional no
clustered definido para la columna Seccion y vea si mejora el rendimiento de
las consultas que filtran por Seccion.

Gustavo Larriera, Microsoft MVP
http://www.linkedin.com/in/gustavolarriera
Este mensaje se proporciona tal como es, sin garantías de ninguna clase.



"Imac_Man" wrote:

Hola,

tengo una tabla con los campos codigo, seccion, nombre. tiene una gran
cantidad de registros el codigo es un autonumerico y tiene un indice
clustered, pero la seccion para todos los registro solo pueden ser 6 codigos
diferentes y normalmente las consultas se hacen por medio de la seccion y no
por el codigopor ende las consultas son lentas, como debo hacer los
indices para que esto funcione repido. muchas gracias de antemano

Saludos

Respuesta Responder a este mensaje
#2 Penta
29/07/2008 - 19:06 | Informe spam
Estimado Gustavo.
Solo por curiosidad, porque "intente" ??
Yo veo que esa es la solución o bien no entendi el problema.

Uns aludo.
Penta.
Respuesta Responder a este mensaje
#3 Gustavo Larriera (MVP)
29/07/2008 - 19:26 | Informe spam
El amigo dice que la columna tiene pocos valores distintos.

Si la columna indizada por el índice no-clustered tiene muy pocos valores
diferentes (como puede ser una columna Sexo por ejemplo) el optimizador de
consultas decidirá no usar el índice y en su lugar ejecutar un scan
secuencial de la tabla.

Por eso recomiendo que intente con un índice y analice el comportamiento de
las consultas (lo mejor es mirar el plan de ejecución) para confirmar si
tener el índice sirve de algo.

Gustavo Larriera, Microsoft MVP
http://www.linkedin.com/in/gustavolarriera
Este mensaje se proporciona tal como es, sin garantías de ninguna clase.



"Penta" wrote:

Estimado Gustavo.
Solo por curiosidad, porque "intente" ??
Yo veo que esa es la solución o bien no entendi el problema.

Uns aludo.
Penta.

Respuesta Responder a este mensaje
#4 Alejandro Mesa
29/07/2008 - 20:15 | Informe spam
Penta,

Solo voy a ampliar lo dicho por gustavo. Si el # de valores diferentes son
pocos (baja selectividad), entonces cuandos hagas un query como:

select codigo, seccion, nombre
from la_tabla
where seccion = '0101'

el numero de filas pueden ser unas cuantas y por lo tanto, leer el indice
nonclustered para luego leer el indice clustered (Key Lookup) puede ser mas
costoso que escanear el indice clustered.

Depende de el numero de columnas en el indice clustered y el numero de
columnas en la sentencia select, asi se podra optimizar la lectura mediante
un indice nonclustered que tambien incluya el resto de columnas referenciadas
por la select. En este caso que el OP expone, solo hay tres columnas en la
tabla y posiblemente se referencien las tres, asi que crear un indice
nonclustered por [seccion] que tambien incluya [nombre], es como duplicar la
tabla. Que pasa si la sentencia solo referencia las columnas [codigo] y
[seccion], pues en ese caso el indice nonclustered tendria todas las columnas
necesarias (recuerda que la llave de el indice clustered tambien estara
presente en el indice nonclustered) y ademas el indice sera mas pequenio en
tamanio asi que leer todo desde el indice nonclustered sera menos costoso.

Ejemplo:

En la db [northwind], la tabla [customers] tiene como clave primaria a la
columna [customerid] y usa indice clustered. Tenemos un indice por [city],
sin ninguna otra columna que se haya incluido.

el primer query solo referencia las columnas [customerid] y [city], asi que
el indice por [city] cubre todas las columnas referenciadas por el query y
ademas es mas angosto (mas filas por pagina) que le clustered, por lo que
usar ese indice para leer la data puede ser menos costoso que usar el
clustered. Si hacemos otro query y adicionamos la columna [companyname] en la
lista de columnas, entonces como el indice por [city] no tiene esta columna
ni en la llave ni en las columnas incluidas, entonces sql server tendra que
hacer una operacion "key lookup" que incluye leer el indice nonclustered,
tomar la llave de el clustered e ir y leer el resto de la data, osea
[companyname], o tambien puede escanear el indice clustered y traer la data
requerida sin ir al nonclustered, pero eso lo decide el optimizador al
escojer la operacion menos costosa. Si volvemos a ejecutar el mismo query que
referencia a la columna [companyname] pero antes creamos un indice por [city]
y que incluya la columna [companyname], entonces este indice tendra las tres
columnas referenciadas por el query y ademas el numero de columnas en este
indice es mucho menor que el numero de columnas en el indice clustered, por
lo que al estar toda la data necesaria en este indice y ademas es mas nagosto
que el clustered, entonces el optimizador puede optar por usarlo.

use northwind
go

set showplan_text on
go

select customerid, city
from dbo.customers
where city = 'Sao Paulo'
go

select customerid, companyname, city
from dbo.customers
where city = 'Sao Paulo'
go

set showplan_text off
go

create nonclustered index customers_city_nu_nc_ix
on dbo.customers(city)
include (companyname)
go

set showplan_text on
go

select customerid, companyname, city
from dbo.customers
where city = 'Sao Paulo'
go

set showplan_text off
go

drop index customers_city_nu_nc_ix
on dbo.customers
go

Resultado:

- Query 1

|--Index Seek(OBJECT:([Northwind].[dbo].[Customers].[City]),
SEEK:([Northwind].[dbo].[Customers].[City]=[@1]) ORDERED FORWARD)

- Query 2

|--Clustered Index
Scan(OBJECT:([Northwind].[dbo].[Customers].[PK_Customers]),
WHERE:([Northwind].[dbo].[Customers].[City]=N'Sao Paulo'))

- Query 3

|--Index
Seek(OBJECT:([Northwind].[dbo].[Customers].[customers_city_nu_nc_ix]),
SEEK:([Northwind].[dbo].[Customers].[City]=[@1]) ORDERED FORWARD)


Si te fijas bien, en el primer query el optimizador opta por usar el indice
nonclustered por [city] ya que solo se referencian las columnas [city] y
[customerid], las cuales son parte de el indice.

En el segundo query, al incluirse la columna [companyname], el optimizador
opta por escanear el indice clustered puesto que no hay un indice
nonclustered que contenga todas las columnas referenciadas y posiblemente la
operacion "key lookup" sea mas costosa.

En el tercero el optimizador opta por usar el nuevo indice nonclustered, el
cual contiene como llave la columna [city], tambien incluye la columna
[customerid] por ser la llave de el indice clustered. Tambien se uso la
clausula "include" para incluir la columna [companyname] y por lo tanto este
indice contine toda la data necesaria para satisfacer el pedido y ademas es
mas angosto que el indice clustered.


AMB


"Penta" wrote:

Estimado Gustavo.
Solo por curiosidad, porque "intente" ??
Yo veo que esa es la solución o bien no entendi el problema.

Uns aludo.
Penta.

Respuesta Responder a este mensaje
#5 Penta
29/07/2008 - 21:31 | Informe spam
Estimados Gustavo y Alejandro
Se entendió a la perfección :)

Duda:
Es posible que el motor elija en cierta oportunidad usar el indice y
luego No usarlo ?? si es asi, supongo que siempre usará la manera mas
rapida ?? si no es asi como lo fuerzo a elegir el indice ??

Ps. Lastima que en el curso de administracion NO pongan enfasis en
estas cosas.

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