2009-08-31 18 views
7

Tengo un procedimiento almacenado en SQL Server 2005 y cuando lo ejecuto y miro su plan de ejecución me doy cuenta de que está haciendo un escaneo de índice agrupado, y esto le está costando el 84%. He leído que tengo que modificar algunas cosas para obtener una búsqueda de índice agrupado allí, pero no sé qué modificar.¿Qué debo hacer para obtener una búsqueda de índice agrupado en lugar de escaneo de índice agrupado?

Agradeceré cualquier ayuda con esto.

Gracias,

Brian

+1

¿Qué hay de la consulta y el esquema de la tabla? –

Respuesta

19

Sin ningún detalle es difícil de adivinar cuál es el problema, e incluso si es un problema en absoluto. La elección de un escaneo en lugar de una búsqueda podría estar motivada por muchos factores:

  • La consulta expresa un conjunto de resultados que cubre toda la tabla. Es decir. la consulta es simple SELECT * FROM <table>. Este es un caso trivial que estaría perfectamente cubierto por un escaneo de índice clonado sin necesidad de considerar nada más.
  • El optimizador no tiene alternativas:
    • la consulta expresa un subconjunto de toda la tabla, pero el predicado de filtrado está en columnas que no son parte de la clave agrupada y no hay índices no clustred en esas columnas ya sea. Estos no son un plan alternativo que no sea un escaneo completo.
    • La consulta tiene predicados de filtrado en columnas en la clave de índice clúster, pero no son SARGable. Por lo general, el predicado de filtrado debe ser reescrito para hacerlo SARGABLE, la reescritura adecuada depende de cada caso. Un problema más sutil puede aparecer debido a las reglas de conversión implícitas, ej. el predicado de filtrado es WHERE column = @value pero la columna es VARCHAR (Ascii) y @value es NVARCHAR (Unicode).
    • La consulta tiene predicados de filtrado SARGale en columnas en la clave agrupada, pero la columna situada más a la izquierda no está filtrada. Es decir. el índice clustred está en las columnas (foo, bar) pero la cláusula WHERE está en bar solo.
  • El optimizador elige un escaneo.
    • cuando la alternativa es un índice no agrupado luego escanear (o rango buscan), pero la elección es una de usar el índice agrupado la causa puede ser generalmente seguido hasta el index tipping point debido a la falta de no agrupado cobertura de índice para la proyección de consulta. Tenga en cuenta que esta no es su pregunta, ya que espera una búsqueda de índice agrupado, no una búsqueda de índice no agrupada (asumiendo que la pregunta es 100% precisa y documentada ...)
    • Estimaciones de cardinalidad. El cálculo del costo de la consulta se basa en las estadísticas de las claves del índice agrupado que proporcionan una estimación de la cardinalidad del resultado (es decir, cuántas filas coincidirán). En una consulta simple Esto no puede suceder, ya que cualquier estimación para una búsqueda o búsqueda de rango será menor que la de un análisis, sin importar cuán fuera de las estadísticas, pero en una consulta complejo, con combinaciones y filtros en varias tablas , las cosas son más complejas y el plan puede incluir un escaneo donde se esperaba una búsqueda porque el optimizador de consultas puede elegir el plan en el cual la orden de evaluación de la unión se invierte a lo que el observador espera. La elección de orden inverso puede ser correcta (la mayoría de las veces) o puede ser problemática (generalmente debido a que las estadísticas son obsoletas o al olfateo de parámetros).
    • Una garantía de pedido. Un escaneo producirá resultados en un orden garantizado y los elementos más altos en el árbol de ejecución pueden beneficiarse de este orden (por ej., Se puede eliminar un ordenamiento o un spool, o se puede usar un join merge en lugar de combinaciones hash/anidado). En general, el costo de consulta es mejor como resultado de elegir una ruta de acceso aparentemente más lenta.

Estos son algunos consejos rápidos por las que un recorrido de índice agrupado puede estar presente cuando se espera un índice agrupado buscar. La pregunta es extremadamente genérica y es imposible dar una respuesta 'por qué', aparte de confiar en una bola 8. Ahora bien, si tomo su pregunta para que esté correctamente documentada y articulada correctamente, entonces, para esperar que un índice agrupado busque, significa que está buscando un registro único basado en un valor clave clusionado. En este caso, el problema tiene que ser con la capacidad de SARG de la cláusula WHERE.

+0

"En una consulta simple Esto no puede suceder, ya que cualquier estimación para una búsqueda o búsqueda de rango será menor que la de un escaneo" ... no es verdad ... Si solo el 10% de las filas tienen 'Especial = verdadero (1) ', luego la consulta simple' Seleccionar * De la tabla donde Especial = 0' Siempre elegirá una tabla Escanear. Este es el caso incluso cuando existe un índice en la columna Especial, siempre que el índice no sea el índice agrupado. (Si el índice es el índice agrupado, entonces el optimizador, por supuesto, elegirá una búsqueda de rango.) –

+0

@Charles: pero ese es el 'punto de inflexión del índice' en el trabajo, que acabo de mencionar. Por cierto, su consulta de ejemplo no es "simple" (es decir, Trivial, consulte http://msdn.microsoft.com/en-us/library/aa226174%28SQL.70%29.aspx): "una instrucción SELECT donde todos los las columnas están en un único índice de cobertura y no hay otro índice que tenga ese conjunto de columnas ". –

+0

si eso es lo que quiere decir con "Simple", entonces puedo estar de acuerdo técnicamente, pero en contexto, sin esa aclaración en cuanto a su significado de la palabra "simple", el lector obtendría una impresión muy diferente e incorrecta. Si pones la palabra 'simple' entre comillas o resaltada, con la definición de yr en parens o como nota al pie, entonces bien ... De lo contrario, el lector asume que cualquier consulta 'simple' no tendrá este problema, y ​​eso es incorrecto, para las razones por las que mencionas ... para exacerbar el problema, a continuación, define semi-definido el complejo como relacionado con la complejidad de la unión, que no está relacionado con el problema de las propinas. –

5

si la consulta incldues más de un cierto porcentaje de las filas de la tabla, el optimizador elegirán a hacer una exploración en lugar de una búsqueda, porque predice que lo hará requieren menos IO de disco en ese caso (para una búsqueda, necesita un disco IO por nivel en el índice para cada fila que devuelve), mientras que para una exploración solo hay una IO de disco por fila en toda la tabla.

Entonces, si los hay, digamos 5 niveles en el índice b-tree, entonces si la consulta generará más del 20% de las filas en la tabla, es más barato leer toda la tabla que hacer 5 IO para cada de las filas del 20% ...

¿Puede limitar el resultado de la consulta un poco más, para reducir el número de filas devueltas por este paso en el proceso? Eso lo ayudaría a elegir la búsqueda sobre el escaneo.

Cuestiones relacionadas