2009-12-28 9 views
20

Estoy tratando de mejorar el rendimiento en una consulta que se ejecuta muy lentamente. Después de pasar por el plan de ejecución real; Descubrí que Clustered Index Seek ocupaba el 82%. ¿Hay alguna forma de que mejore el rendimiento en una búsqueda de índice ? A continuación se muestra una imagen del problema Index Search del plan de ejecución, así como del índice y la tabla que está utilizando.Cómo mejorar el rendimiento en un índice agrupado Buscar

alt text http://img340.imageshack.us/img340/1346/seek.png

Índice:

/****** Object: Index [IX_Stu] Script Date: 12/28/2009 11:11:43 ******/ 
CREATE CLUSTERED INDEX [IX_Stu] ON [dbo].[stu] 
(
[StuKey] ASC 
)WITH (PAD_INDEX = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY] 

de mesa (algunas columnas omitidas por razones de brevedad):

CREATE TABLE [dbo].[stu](
[StuCertKey] [int] IDENTITY(1,1) NOT NULL, 
[StuKey] [int] NULL 
CONSTRAINT [PK_Stu] PRIMARY KEY NONCLUSTERED 
(
[StuCertKey] ASC 
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 80) ON [PRIMARY] 
) ON [PRIMARY] 
+2

"It Depends." ... – RBarryYoung

+0

¿Es una mala idea para mí tener el índice agrupado en algo que no sea la clave principal? La consulta nunca usa la clave principal, así que pensé que sería mejor crear el índice agrupado en la columna que está unida más (StuKey) –

+1

¿Podría publicar la consulta? Además, hay muchas filas en la tabla y aproximadamente cuántas devuelven la consulta. – dan

Respuesta

14

estoy generalizando aquí, pero ...

un índice agrupado buscan es, en su mayor parte, el mejor de los casos. La única forma en que se me ocurre mejorar el rendimiento sería:

  • Actualice la consulta para devolver menos filas/columnas, si es posible;
  • Desfragmenta o reconstruye el índice;
  • Particione el índice en múltiples discos/servidores.

Si solo devuelve 138 filas, y es tan lento ... ¿tal vez esté siendo bloqueado por algún otro proceso? ¿Está probando esto de forma aislada o hay otros usuarios/procesos en línea al mismo tiempo? O tal vez es incluso un problema de hardware, como una falla en el disco.

+0

Podría haber un par de otros usuarios pero no muchos. También esta es una consulta DW. Si no hay actualizaciones en el db, entonces no debería haber bloqueos que me impidan leer, ¿verdad? –

+0

Algún otro proceso podría estar haciendo un 'SELECT * FROM stu' sin filtro, recuperando las 8 millones de filas; eso definitivamente desaceleraría otras consultas debido al cuello de botella de E/S. Poco probable, pero posible. – Aaronaught

1

¿Has probado un poco de mantenimiento en este índice? Como desfragmentarlo? Parece realmente extraño que cueste TANTO (120.381). La búsqueda de índice es la operación de índice más rápida, no debería tomar tanto tiempo. ¿Puedes publicar la consulta?

+0

Prefiero no publicar la consulta. Déjame echar un vistazo a lo que defrag hace ... –

+0

¿Alguna sugerencia sobre cuánta des-fragmentación es demasiada des-fragmentación? –

0

¿Reconstruir el índice y calcular las estadísticas?

La única otra forma en que puedo pensar para acelerarlo es dividir la mesa, lo que puede o no ser posible.

+0

Intentó reconstruir índices y estadísticas. sin suerte, sin embargo. Podría estar buscando particionar las tablas a continuación. ¿Es esa una buena solución para búsquedas lentas? –

3

Pensamientos ...

  • Por qué está agrupado IX_Stu? Internamente, SQL Server agrega un "únicoificador" de 4 bytes a índices agrupados no únicos. ¿Cuál es la justificación? Esto también hincha su PK también

  • ¿Cuál es la consulta real que está ejecutando?

  • Finalmente, ¿por qué FILLFACTOR 80%?

Editar:

  • Un FILLFACTOR "normal" sería del 90%, pero esto es una regla de oro solamente

  • Una consulta de unión 11? Es muy probable que sea tu problema.¿Cuáles son sus JOINs, WHERE cláusulas, etc.? ¿Cuál es el plan de texto completo?

+2

Con respecto a su primera pregunta, hice IX_Stu agrupado porque se va a usar para la mayoría de las combinaciones. Pensé que mejoraría el rendimiento, ¿estoy mezclado aquí? Segunda pregunta, prefiero no publicar la consulta en Internet si puedo evitarla. Es muy grande con once uniones si eso te ayuda ... Última pregunta: Creé el índice a través de un estudio de administración y no por una consulta. Aparentemente, el estudio de administración agregó el FILLFACTOR al 80%. ¿Podría eso potencialmente causar problemas? –

1

¿Qué pasa si su disco de código DONDE criterios, así:

SELECT StuCertKey, StuKey FROM stu 
WHERE stuKey in (/* list 50 values of StuKey here */) 

Si sigue siendo muy lento, que tienen un problema interno de algún tipo. Si es más rápido, entonces el índice no es su cuello de botella, es JOINs lo que está haciendo para crear el filtro WHERE.

Tenga en cuenta que SELECT * puede ser muy lento si hay muchas columnas grandes, y especialmente si hay BLOB.

6

Una búsqueda de rango de índice agrupado que devuelve 138 filas no es su problema.

Técnicamente se puede mejorar el rendimiento de buscar al hacer que el índice agrupado más estrecho:

Ambos pueden tener un impacto bastante dramático en el tiempo de búsqueda de rango, ya que reducen el IO y la necesidad de alcanzar lecturas físicas. Por supuesto, como suele suceder, el resultado variará en un gran número de otros factores, como qué columnas proyecta (desalojar una columna proyectada en la unidad de asignación BLOB puede tener efectos adversos en determinadas consultas). Como nota al margen, generalmente la fragmentación tendrá un impacto marginal en un escaneo de tan corto alcance. De nuevo, depende.

Pero como digo, dudo mucho que este sea su verdadero problema. Solo ha publicado partes seleccionadas del plan y los resultados de su propio análisis. La verdadera causa raíz puede estar completamente en otro lugar.

1

Algunos consejos generales: cuando tengo que hacer la optimización de la consulta, empiezo por escribir lo que creo que debe ser el plan de ejecución.

Una vez que he decidido lo que creo que debe ser el plan de ejecución, trato de hacer que la consulta se ajuste a este plan. Las técnicas para hacer esto son diferentes para cada DBMS, y no necesariamente se transfieren de una a la otra, o incluso, a veces, entre diferentes versiones del DBMS.

Lo que hay que tener en cuenta es que el DBMS solo puede ejecutar una unión a la vez: comienza con dos tablas iniciales, las une, y luego toma el resultado de esa operación y lo une a la siguiente tabla. El objetivo en cada paso es minimizar el número de filas en el conjunto de resultados intermedio (más correctamente, para minimizar el número de bloques que se deben leer para producir los resultados intermedios, pero esto generalmente significa menos filas).

+1

Interesante. Digamos que sé que una determinada combinación reduce mi conjunto de 6 millones de filas a aproximadamente 500,000. ¿Mejora el rendimiento el hecho de que ese Join llegue antes que el otro se une o tal vez cree un CTE que contenga el contenido de ese Join y luego lo use en el futuro? –

10

Las búsquedas en el índice agrupado se producen cuando se usan índices no agrupados y no son necesariamente malos.

Considere la siguiente consulta:

SELECT s.StuKey, s.Name, s.Address, s.City, s.State FROM stu s WHERE State='TX' 

Si sólo hay un índice agrupado en Stukey, a continuación, SQL Server sólo tiene 1 posibilidad, debe escanear toda la tabla en busca de filas en las que Estado = "TX' y devuelve esas filas.

Si añade un índice no agrupado en Estado

CREATE INDEX IX_Stu_State on Stu (State) 

servidor SQL tiene ahora una nueva opción. Puede elegir buscar utilizando el índice no agrupado, que producirá las filas donde State = 'TX'. Sin embargo, para que las columnas restantes regresen en SELECT, tiene que buscar esas columnas haciendo una búsqueda de índices agrupados para cada fila.

Si desea reducir las búsquedas del índice agrupado, puede hacer que su índice "cubra" al incluir columnas adicionales en él.

CREATE INDEX IX_Stu_State2 on Stu (State) INCLUDE (name, address, city) 

Este índice ahora contiene todas las columnas necesarias para responder a la consulta anterior. La consulta generará un índice que busca devolver solo las filas donde State = 'TX', y las columnas adicionales pueden extraerse del índice no agrupado, de modo que las búsquedas del índice agrupado desaparecen.

1

Compruebe el índice de estadísticas.

reCalcular las estadísticas de índice agrupado resolverá el problema.

en mi caso, estaba buscando 30 registros en 40M recored. el plan de ejecución dice que está pasando por el índice agrupado, pero tomó alrededor de 200ms. y el índice no fue desfragmentado. ¡Después de recalcular sus estadísticas, se está haciendo por debajo de los 10 ms!

Cuestiones relacionadas