Pregunta

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 ; He encontrado que a agrupado búsqueda de índice fue usando un 82%. ¿Hay alguna manera para mí para mejorar el rendimiento en un búsqueda de índice ? A continuación se muestra una imagen del problema búsqueda de índice en el plan de ejecución, así como el índice y la tabla que está utilizando.

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]

Tabla (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]
¿Fue útil?

Solución

Me estoy generalizando aquí, pero ...

Un índice agrupado buscan es, en su mayor parte, el mejor de los casos. Las únicas formas que se me ocurre para mejorar el rendimiento serían:

  • Modificar la consulta para devolver menos filas / columnas, si es posible;
  • Defragment o reconstruir el índice;
  • Se reparte el índice a través de múltiples discos / servidores.

Si sólo está volviendo 138 filas, y es tan lento ... tal vez está siendo bloqueado por algún otro proceso? ¿Está probando de forma aislada, o son otros usuarios / procesos en línea al mismo tiempo? O tal vez es incluso un problema de hardware, como un fallo en el disco.

Otros consejos

índice agrupado busca ocurrir cuando se utilizan los índices no agrupados y no son necesariamente malas.

Tenga en cuenta 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 regresan esas filas.

Si añade un índice no agrupado en Estado

CREATE INDEX IX_Stu_State on Stu (State)

Ahora servidor SQL tiene una nueva opción. Se puede optar por buscar utilizando el índice no agrupado, que producirá las filas en las que Estado = 'TX'. Sin embargo, con el fin de obtener las columnas restantes para regresar en el SELECT, tiene que consultar dichas columnas haciendo un índice agrupado buscar para cada fila.

Si desea reducir el índice agrupado busca, a continuación, puede hacer que su índice de "cobertura" mediante la inclusión de columnas adicionales en el mismo.

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

Este índice contiene ahora todas las columnas necesarias para responder a la consulta anterior. La consulta va a hacer una búsqueda de índice para devolver sólo las filas donde Estado = 'TX', y las columnas adicionales se pueden sacar del índice no agrupado, por lo que el índice agrupado busca desaparecer.

Un índice agrupado rango buscan que los retornos 138 filas no es su problema.

Técnicamente se puede mejorar la búsqueda de la rentabilidad, haciendo que el más estrecho índice agrupado:

Tanto puede tener un impacto dramático en la gama bastante tiempo de búsqueda, ya que reducen la IO y la necesidad de golpe lecturas físicas. Por supuesto, como siempre, el resultado puede variar en un gran número de otros factores, como lo hacen las columnas que proyecto (el desalojo de una columna proyectada en la unidad de asignación BLOB en realidad puede tener efectos adversos en ciertas consultas). Como nota al margen, por lo general la fragmentación tendrá un impacto marginal en un rango de exploración tan corto. Una vez más, depende.

Pero, como digo, dudo mucho que este es su verdadero problema. Sólo se han publicado las partes seleccionadas del plan y los resultados de su propio análisis. La verdadera causa fundamental podrá determinar por completo en otro lugar.

Pensamientos ...

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

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

  • Por último, ¿por qué FILLFACTOR 80%?

Editar:

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

  • Una consulta de combinación 11? Eso es muy probable que su problema. ¿Cuáles son sus combinaciones, las cláusulas WHERE, etc? ¿Cuál es el plan de texto completo?

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

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

Lo que hay que tener en cuenta es que el DBMS sólo puede ejecutar una unen a la vez: se empieza con dos tablas iniciales, se une a ellos, y luego toma el resultado de esa operación y se une a la siguiente tabla. El objetivo en cada paso es reducir al mínimo el número de filas en el conjunto de resultados intermedio (más correctamente, para reducir al mínimo el número de bloques que tienen que ser leído para producir los resultados intermedios, pero esto generalmente significa menor número de filas).

¿Usted ha intentado un poco de mantenimiento en este índice? Al igual que desfragmentar? Parece muy extraño que cuesta mucho QUE (120.381). Búsqueda de índice es la operación de índice más rápido, no debe tomar mucho tiempo. Se puede publicar la consulta?

¿Qué pasa si difícil que el código donde criterios, como esto:

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

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

Tenga en cuenta que SELECT * puede ser muy lento si hay muchos grandes columnas, y sobre todo si hay BLOB.

Comprobar los statictics índice.

volver a calcular las estadísticas de índice agrupado va a resolver el problema.

en mi caso, yo estaba buscando 30 registros en recored 40M. el plan de ejecución dice que va a través del cluster-índice, pero que tomó cerca de 200 ms. y el índice no se desfragmenta. después de volver a calcularlo de las estadísticas, se está haciendo hace bajo 10ms!

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

La única otra forma que se me ocurre para acelerarlo es dividir la tabla, que puede o no puede ser posible.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top