¿Qué impacto tienen las compilaciones SQL en el rendimiento de SQL Server?

20

Estoy perfilando una instancia de SQL Server 2005 y, a través de la SQLServer:SQL Statistics - SQL Compilations/secmétrica de PerfMon , veo que el promedio es de aproximadamente 170.

Saqué SQL Profiler y busqué SP: compilar o SQL: compilar eventos. Aparentemente no existen. Encontré Stored Procedure/SP:Recompiley TSQL/SQL:StmtRecompileeventos. La cantidad de datos que veo en el Profiler sugiere que estos son los eventos incorrectos para mirar, aunque no estoy seguro.

Entonces mis preguntas. Las respuestas a cualquiera de estos serían geniales.

  1. ¿Cómo puedo ver qué se está compilando exactamente en SQL Server?
  2. ¿Elegí las métricas incorrectas para mirar? ¿En Perfmon o SQL Profiler?
  3. Con respecto a Stored Procedure/SP:Recompiley TSQL/SQL:StmtRecompileeventos en SQL ... que no incluyen la métrica Duración. ¿Cómo puedo medir el impacto de estos eventos en el sistema si no proporcionan una forma de ver el impacto del tiempo en el sistema?
AngryHacker
fuente

Respuestas:

33

SQL Compilations / sec es una buena métrica, pero solo cuando se combina con Batch Requests / sec . Por sí solo, las compilaciones por segundo realmente no te dicen mucho.

Está viendo 170. Si la solicitud de lote por segundo es solo 200 (un poco exagerado para el efecto), entonces sí, debe llegar al fondo de la causa (probablemente un uso excesivo de consultas ad hoc y planes de un solo uso). Pero si su requerimiento de lote por segundo mide aproximadamente 5000, entonces 170 compilaciones por segundo no son malas en absoluto. Es una regla general que las compilaciones / seg deben estar al 10% o menos que el total de solicitudes de lote / seg .

Si realmente desea profundizar en lo que se está almacenando en caché, ejecute la siguiente consulta que utiliza los DMV apropiados:

select
    db_name(st.dbid) as database_name,
    cp.bucketid,
    cp.usecounts,
    cp.size_in_bytes,
    cp.objtype,
    st.text
from sys.dm_exec_cached_plans cp
cross apply sys.dm_exec_sql_text(cp.plan_handle) st

Para obtener todos los planes de un solo uso (un recuento):

;with PlanCacheCte as 
(
    select
        db_name(st.dbid) as database_name,
        cp.bucketid,
        cp.usecounts,
        cp.size_in_bytes,
        cp.objtype,
        st.text
    from sys.dm_exec_cached_plans cp
    cross apply sys.dm_exec_sql_text(cp.plan_handle) st
)
select count(*)
from PlanCacheCte
where usecounts = 1

Para obtener una proporción de cuántos planes de recuento de un solo uso tiene en comparación con todos los planes en caché:

declare @single_use_counts int, @multi_use_counts int

;with PlanCacheCte as 
(
    select
        db_name(st.dbid) as database_name,
        cp.bucketid,
        cp.usecounts,
        cp.size_in_bytes,
        cp.objtype,
        st.text
    from sys.dm_exec_cached_plans cp
    cross apply sys.dm_exec_sql_text(cp.plan_handle) st
    where cp.cacheobjtype = 'Compiled Plan'
)
select @single_use_counts = count(*)
from PlanCacheCte
where usecounts = 1

;with PlanCacheCte as 
(
    select
        db_name(st.dbid) as database_name,
        cp.bucketid,
        cp.usecounts,
        cp.size_in_bytes,
        cp.objtype,
        st.text
    from sys.dm_exec_cached_plans cp
    cross apply sys.dm_exec_sql_text(cp.plan_handle) st
    where cp.cacheobjtype = 'Compiled Plan'
)
select @multi_use_counts = count(*)
from PlanCacheCte
where usecounts > 1

select
    @single_use_counts as single_use_counts,
    @multi_use_counts as multi_use_counts,
    @single_use_counts * 1.0 / (@single_use_counts + @multi_use_counts) * 100
        as percent_single_use_counts

En cuanto a las duraciones capturadas a través de un seguimiento de SQL Server, no está disponible para los eventos de recompilación. No es tan significativo ver la duración o el dolor que está causando la compilación del plan, ya que no hay mucho que pueda hacer para una situación caso por caso. La solución es intentar limitar las compilaciones y recompilaciones mediante la reutilización del plan (consultas parametrizadas, procedimientos almacenados, etc.).

Thomas Stringer
fuente
9

Hay tres contadores relevantes que deben registrarse utilizando PerfMon (u otra solución de terceros). El punto clave es registrar estas estadísticas de alguna manera.

  • Estadísticas SQL \ Solicitudes de lote / seg.
  • Estadísticas SQL \ Compilaciones SQL / seg.
  • SQL Statistics \ SQL Re-Compilations / sec

Como mencionó Thomas Stringer , es bueno vigilar la proporción de compilaciones / solicitud de lote. Obviamente, más bajo es mejor, pero solo hay pautas para lo que es "bueno", y solo usted puede decidir qué es aceptable. La cantidad absoluta de ganancia de rendimiento que verá al reducir el número de compilaciones depende de muchos factores.

También me gusta mirar la proporción de recompilaciones / compilación , para tener una idea de la cantidad de reutilización del plan de consulta. De nuevo, más bajo es mejor. En este caso, sin embargo, desea que ocurran recompilaciones en el sistema a medida que cambian las estadísticas (si el DB es de solo lectura y tiene recompilaciones ... algo puede estar mal). Igual que dije anteriormente, solo hay pautas para lo que es "bueno".

Lo que realmente quiere hacer es cambiar estos números a lo largo del tiempo, por lo que si ve un gran aumento en cualquiera de las proporciones, se implementó algo que no usa los planes de consulta correctamente (idealmente, esto se detecta durante las pruebas): use Shark's consultas de análisis para encontrar a los culpables. Además, aquí hay uno para encontrar consultas frecuentemente compiladas:

SELECT TOP 50
    qs.plan_generation_num,
    qs.execution_count,
    qs.statement_start_offset,
    qs.statement_end_offset,
    st.text
    FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
    WHERE qs.plan_generation_num > 1
    ORDER BY qs.plan_generation_num DESC

Si también está grabando estadísticas para el uso de la CPU, todas las estadísticas se pueden correlacionar juntas para descubrir cuánto duele y cuánto ayudan sus soluciones. En la práctica, he descubierto que incluso una sola estrategia de plan de consulta incorrecta en un núcleo sproc puede poner de rodillas a un servidor; obviamente YMMV.

Jon Seigel
fuente