sql >> Base de Datos >  >> RDS >> Database

Establecimiento e identificación de objetivos de fila en planes de ejecución

Introducción

La documentación del producto de SQL Server es un poco ligera sobre el tema de objetivos de fila . Las principales referencias oficiales están en:

  • Sugerencias (Transact-SQL) – Consulta (FAST y DISABLE_OPTIMIZER_ROWGOAL pistas)
  • DBCC TRACEON:indicadores de seguimiento (Transact-SQL) (indicador de seguimiento 4138)
  • Una consulta puede tardar mucho tiempo en ejecutarse si el optimizador de consultas usa el operador Superior (KB 2667211)

Cuando las personas solicitan más información que la contenida allí, normalmente les remito uno o más de los siguientes:

  • Objetivos de fila en acción por el equipo de optimización de consultas de SQL Server
  • Objetivos de fila revisados:guía de sugerencias FAST también por parte del equipo de optimización de consultas de SQL Server
  • Los goles en fila se vuelven pícaros por Bart Duncan
  • Dentro del Optimizer:Fila de objetivos en profundidad por mí
  • El consejo de sintonización de SSIS que todos extrañan de Rob Farley

Para resumir brevemente:la función de objetivo de fila permite que el optimizador genere un plan de ejecución (o parte(s) de un plan de ejecución) con el objetivo de devolver una cierta cantidad de filas rápidamente. Esto contrasta con el comportamiento normal (sin un objetivo de fila), cuyo objetivo es encontrar un plan optimizado para el conjunto de resultados potencial completo.

Una estrategia de objetivo de fila generalmente significa favorecer las operaciones de navegación que no bloquean (por ejemplo, uniones de bucles anidados, búsquedas de índices y búsquedas) sobre operaciones de bloqueo basadas en conjuntos como clasificación y hash. Esto puede ser útil siempre que el cliente pueda beneficiarse de un inicio rápido y un flujo constante de filas (quizás con un tiempo de ejecución general más prolongado; consulte la publicación anterior de Rob Farley). También existen los usos más obvios y tradicionales, p. en la presentación de resultados una página a la vez.

Naturalmente, hay un elemento de riesgo involucrado con un plan de objetivos de fila. Si todo se desarrolla en términos generales como espera el optimizador (dada la información disponible y las suposiciones de modelado realizadas), el plan de ejecución comenzará a transmitir la cantidad solicitada de filas de manera más rápida y eficiente de lo que hubiera sido sin el objetivo de la fila.

Desafortunadamente, cuando la estrategia de gol de fila sale mal, puede ser un desastre de rendimiento (ver la publicación de Bart Duncan). Esto puede suceder, por ejemplo, cuando el optimizador tiene información incompleta, encuentra una distribución de datos desfavorable o hace una suposición insegura. En cualquier caso, la causa del bajo rendimiento casi siempre es que se deben procesar muchas más filas en el momento de la ejecución de las que esperaba el optimizador.

Puede ser muy útil para identificar las áreas del plan de ejecución afectadas por un objetivo de fila, porque nos ayuda a comprender por qué el optimizador tomó las decisiones que tomó. Esto es particularmente importante cuando la lógica del objetivo de la fila produce un resultado adverso. Sin comprender el papel que desempeña el objetivo de la fila, podría parecer que el optimizador simplemente subestimó la cantidad de filas, lo que lleva a las personas a buscar en los lugares equivocados (por ejemplo, estadísticas) para encontrar una causa raíz.

Establecer objetivos de fila

Es mucho más fácil buscar los efectos del objetivo de fila si uno sabe qué tipo de cosas pueden hacer que se establezca un objetivo de fila en primer lugar. La documentación oficial a menudo habla de objetivos de fila asociados con las palabras clave TOP , FAST , IN y EXISTS . Esto puede dejar al lector con una comprensión incompleta o engañosa, por lo que vale la pena tomarse un momento para aclarar algunos aspectos.

Quiero enfatizar desde el principio que usar palabras clave específicas de T-SQL en una consulta no garantiza que se establecerá un objetivo de fila . La documentación oficial menciona ciertas palabras clave para ayudar a las personas a identificar escenarios comunes donde los objetivos de fila pueden introducirse, sin entrar en demasiados tecnicismos.

Un segundo punto general a tener en cuenta es que un objetivo de fila solo se establece cuando el objetivo sería inferior a la estimación habitual . Después de todo, no tiene mucho sentido generar un fragmento de plan optimizado para 100 filas si se espera que todo produzca 50 filas de todos modos. Para ser más claro, este punto siempre se aplica a todas las formas en que se puede establecer un objetivo de fila. Si espera un objetivo de fila, pero no lo ve, esta es una causa probable.

Finalmente, para el preámbulo, tenga en cuenta que los objetivos de fila son una cosa de optimización basada en costos; un objetivo de fila afecta las opciones del optimizador, por lo que si no hay elecciones que hacer (es decir, un plan trivial) no hay efecto de objetivo de fila.

Veamos ahora las cosas que pueden establecer un objetivo de fila:

RÁPIDO y SUPERIOR

Usando el FAST la sugerencia de consulta es una forma confiable de establecer un objetivo de fila en la raíz del plan de ejecución (sujeto a las excepciones generales señaladas anteriormente). A SET ROWCOUNT n también establece un objetivo de fila de nivel superior similar (cuando n no es cero, por supuesto) para las sentencias a las que se aplica.

Escribiendo un TOP La cláusula en una consulta también suele dar como resultado un objetivo de fila. Siempre que el plan de ejecución terminado cuente con un operador superior físico, es probable que al menos una parte del plan debajo del operador superior se haya visto afectado por un objetivo de fila (nuevamente, se aplican los términos y condiciones generales).

Tenga en cuenta que los principales operadores introducidos por el optimizador de consultas (sin un TOP especificado por consulta cláusula) también puede establecer un objetivo de fila. Esto es importante, porque hay todo tipo de formas en que esto puede suceder, por ejemplo, cuando se filtra por un número de fila simple, como se muestra en la siguiente consulta de AdventureWorks:

SELECT
    THN.RowNum,
    THN.TransactionID 
FROM 
(
    SELECT 
        TH.TransactionID, 
        RowNum = 
            ROW_NUMBER() OVER (
                ORDER BY TH.TransactionID ASC)
    FROM Production.TransactionHistory AS TH
    WHERE
        TH.ProductID = 400
) AS THN
WHERE
    THN.RowNum >= 10
    AND THN.RowNum < 20
ORDER BY
    THN.RowNum ASC;

El plan de ejecución para esa consulta incluye un operador superior agregado por el optimizador (para limitar el número de filas procesadas a 20):