¿Por qué NO utilizaría la opción de SQL Server "optimizar para cargas de trabajo ad hoc"?


49

He estado leyendo algunos excelentes artículos sobre el almacenamiento en caché de planes de SQL Server por Kimberly Tripp como este: http://www.sqlskills.com/blogs/kimberly/plan-cache-and-optimizing-for-adhoc-workloads/

¿Por qué hay incluso una opción para "optimizar las cargas de trabajo ad hoc"? ¿No debería estar esto siempre encendido? Ya sea que los desarrolladores usen SQL ad-hoc o no, ¿por qué no habilitaría esta opción en cada instancia que lo admita (SQL 2008+), reduciendo así la acumulación de caché?

Respuestas:


45

El equipo de desarrollo de SQL Server trabaja bajo el principio de la menor sorpresa, por lo que SQL Server generalmente tiene nuevas características deshabilitadas con el fin de mantener el comportamiento de las versiones anteriores.

Sí, optimizar para cargas de trabajo adhoc es excelente para reducir la hinchazón de caché del plan, ¡pero siempre pruébelo primero!

[Editar: Kalen Delaney cuenta una anécdota interesante de que le preguntó a uno de sus amigos ingenieros de Microsoft si habría circunstancias en las que no sería apropiado habilitar esto. Vuelve varios días después para decir: imagine una aplicación que tenga MUCHAS consultas diferentes, y cada consulta se ejecuta exactamente dos veces en total. Entonces podría ser inapropiado. ¡Basta decir que no hay muchas aplicaciones como esa!]

[Editar: si la mayoría de sus consultas se ejecutan más de una vez (no exactamente dos veces); probablemente sea inapropiado. La regla general sería activarlo si hay muchas consultas ad hoc de un solo uso en la base de datos; sin embargo, todavía no hay muchas aplicaciones como esa.]


99
Las nuevas funciones de +1 están muy, muy raramente activadas de forma predeterminada. Realmente no puedo pensar en ninguna buena razón para no activar esta función específica; en el peor de los casos, todas sus consultas son de un solo uso y de todos modos no se beneficiarían del almacenamiento en caché.
Aaron Bertrand

1
Esta es una respuesta "segura" basada en el sentido común y no aborda la pregunta. El autor de la pregunta quiere saber específicamente el caso de uso para cuando NO activar esta función es mejor.
MikeTeeVee

2
MikeTeeVee: puede ser una respuesta segura, pero esta es una de esas características en las que realmente no puedo pensar en una razón para no habilitarla. Como es tan increíble, ¡solo quería explicar por qué estaba apagado de forma predeterminada!
Peter Schofield

21

A continuación se muestra un pequeño código que lo ayudará a decidir si "cambiar la optimización para cargas de trabajo ad hoc ON / OFF" será beneficioso o no. Normalmente verificamos esto como parte de nuestro control de salud para servidores internos y de clientes.

Es la opción más segura para habilitar y Brad lo describe bien aquí y Glenn Berry aquí .

--- for 2008 and up .. Optimize ad-hoc for workload 
IF EXISTS (
        -- this is for 2008 and up
        SELECT 1
        FROM sys.configurations
        WHERE NAME = 'optimize for ad hoc workloads'
        )
BEGIN
    DECLARE @AdHocSizeInMB DECIMAL(14, 2)
        ,@TotalSizeInMB DECIMAL(14, 2)
        ,@ObjType NVARCHAR(34)

    SELECT @AdHocSizeInMB = SUM(CAST((
                    CASE 
                        WHEN usecounts = 1
                            AND LOWER(objtype) = 'adhoc'
                            THEN size_in_bytes
                        ELSE 0
                        END
                    ) AS DECIMAL(14, 2))) / 1048576
        ,@TotalSizeInMB = SUM(CAST(size_in_bytes AS DECIMAL(14, 2))) / 1048576
    FROM sys.dm_exec_cached_plans

    SELECT 'SQL Server Configuration' AS GROUP_TYPE
        ,' Total cache plan size (MB): ' + cast(@TotalSizeInMB AS VARCHAR(max)) + '. Current memory occupied by adhoc plans only used once (MB):' + cast(@AdHocSizeInMB AS VARCHAR(max)) + '.  Percentage of total cache plan occupied by adhoc plans only used once :' + cast(CAST((@AdHocSizeInMB / @TotalSizeInMB) * 100 AS DECIMAL(14, 2)) AS VARCHAR(max)) + '%' + ' ' AS COMMENTS
        ,' ' + CASE 
            WHEN @AdHocSizeInMB > 200
                OR ((@AdHocSizeInMB / @TotalSizeInMB) * 100) > 25 -- 200MB or > 25%
                THEN 'Switch on Optimize for ad hoc workloads as it will make a significant difference. Ref: http://sqlserverperformance.idera.com/memory/optimize-ad-hoc-workloads-option-sql-server-2008/. http://www.sqlskills.com/blogs/kimberly/post/procedure-cache-and-optimizing-for-adhoc-workloads.aspx'
            ELSE 'Setting Optimize for ad hoc workloads will make little difference !!'
            END + ' ' AS RECOMMENDATIONS
END

7

Piense en un servidor de producción que atiende solo 5 consultas diferentes, pero varios miles de ellas por segundo. Usted es el equipo de desarrollo de Microsoft SQL Server. Vas a jugar con el almacenamiento en caché del plan. ¿Activa este comportamiento de manera predeterminada cuando sabe que algunos de sus clientes más grandes y críticos (por ejemplo, la implementación interna de SAP de Microsoft) trabajan en el mismo campus y usan la misma cafetería que usted?


Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Paul White

7

Cuando activa la opción " Optimizar para cargas de trabajo ad hoc ", provocará que las consultas ad-hoc que se ejecutan la segunda vez sean tan lentas como la primera, porque estará compilando un plan de ejecución y extrayendo los mismos datos ( sin caché) esas primeras 2 veces.
Puede que esto no sea un gran problema, pero lo notará cuando pruebe consultas.
Entonces, ¿qué sucede ahora, sin esta opción activada y un caché lleno de consultas Ad-Hoc 1-Off?

El algoritmo de gestión de almacenamiento en caché:

Cuando se introdujo esta función de optimización, también se actualizó el algoritmo de gestión de almacenamiento en caché.
El artículo de Kimberly Tripp también hace referencia a la publicación de Kalen Delaney sobre este cambio de algoritmo.
Ella lo explica mejor:

El cambio en realidad calcula un tamaño de caché del plan en el que SQL Server reconoce que hay presión de memoria y comenzará a eliminar los planes de la caché. Los planes que se eliminarán son los planes baratos que no se han reutilizado, y esto es BUENO.

Esto significa que esos molestos planes de un solo temporizador serán los primeros en irse cuando necesite liberar recursos.

Entonces ahora la pregunta es:

    " ¿Por qué NECESITAMOS 'Optimizar para cargas de trabajo ad hoc' cuando SQL Server se encarga de eliminar los planes no utilizados cuando es necesario? "

Mi respuesta a esto es, si regularmente tiene una tonelada de montones dinámicos de sql de anuncios no parametrizados -hoc consultas, entonces tiene mucho sentido activar esta función.
Desea evitar ejercer presión sobre los recursos del sistema, de modo que fuerce la eliminación del plan en caché / datos después de que haya utilizado el espacio máximo de memoria caché.

¿Cómo sé cuándo necesito activar esto?

Aquí hay una consulta que escribí para mostrarle cuántos Planes Ad-Hoc tiene actualmente en caché y cuánto espacio en disco están consumiendo (los resultados cambiarán a lo largo del día, así que pruébelo durante un momento de gran carga):

--Great query for making the argument to use "Optimize for Ad Hoc Workloads":
SELECT S.CacheType, S.Avg_Use, S.Avg_Multi_Use,
       S.Total_Plan_3orMore_Use, S.Total_Plan_2_Use, S.Total_Plan_1_Use, S.Total_Plan,
       CAST( (S.Total_Plan_1_Use * 1.0 / S.Total_Plan) as Decimal(18,2) )[Pct_Plan_1_Use],
       S.Total_MB_1_Use,   S.Total_MB,
       CAST( (S.Total_MB_1_Use   * 1.0 / S.Total_MB  ) as Decimal(18,2) )[Pct_MB_1_Use]
  FROM
  (
    SELECT CP.objtype[CacheType],
           COUNT(*)[Total_Plan],
           SUM(CASE WHEN CP.usecounts > 2 THEN 1 ELSE 0 END)[Total_Plan_3orMore_Use],
           SUM(CASE WHEN CP.usecounts = 2 THEN 1 ELSE 0 END)[Total_Plan_2_Use],
           SUM(CASE WHEN CP.usecounts = 1 THEN 1 ELSE 0 END)[Total_Plan_1_Use],
           CAST((SUM(CP.size_in_bytes * 1.0) / 1024 / 1024) as Decimal(12,2) )[Total_MB],
           CAST((SUM(CASE WHEN CP.usecounts = 1 THEN (CP.size_in_bytes * 1.0) ELSE 0 END)
                      / 1024 / 1024) as Decimal(18,2) )[Total_MB_1_Use],
           CAST(AVG(CP.usecounts * 1.0) as Decimal(12,2))[Avg_Use],
           CAST(AVG(CASE WHEN CP.usecounts > 1 THEN (CP.usecounts * 1.0)
                         ELSE NULL END) as Decimal(12,2))[Avg_Multi_Use]
      FROM sys.dm_exec_cached_plans as CP
     GROUP BY CP.objtype
  ) AS S
 ORDER BY S.CacheType

Resultados: ingrese la descripción de la imagen aquí

No voy a decir, " Cuando tienes X MB " o " Si X% de tu Ad Hoc es de un solo uso " para activar esto.
No afecta a Sprocs, disparadores, vistas o SQL parametrizado / preparado, solo las consultas ad-hoc.
Mi recomendación personal es activarlo en su entorno de producción, pero considere dejarlo en su entorno de desarrollo.
Digo esto solo para Dev, porque si está optimizando una consulta que tarda un minuto o más en ejecutarse, entonces no desea ejecutarla 3 veces antes de que pueda ver qué tan rápido irá con el almacenamiento en caché, cada una vez que lo edita para encontrar el mejor diseño de optimización.
Si su trabajo no implica hacer esto todo el día, entonces enloquezca y pídale a su DBA que lo encienda en todas partes.


0

"¿Por qué no debería usar ...?" En el curso de algunas investigaciones de rendimiento, extraer planes de la memoria caché del plan casi en tiempo real, mientras que observar la utilización de los recursos puede ser muy útil. "Optimizar para cargas de trabajo ad hoc" puede alterar eso, ya que los planes de resguardo ad hoc no devolverán un plan al consultar el caché. En un caso como ese, si la consulta y el plan no pueden identificarse de otra manera, la configuración podría activarse y desactivarse nuevamente en aras de la investigación. Tenga en cuenta que un cambio en la configuración de las consultas de efectos compiladas a partir de ese momento. Además, cada vez que cambie una propiedad de 'servidor', verifique una instancia que no sea de producto en la misma versión para verificar si el cambio vaciará o no el caché del plan. Personalmente odio ser sorprendido por eso. (Por ejemplo, cambiar maxdop a nivel de servidor normalmente vacía la caché del plan,

"El apéndice del plan compilado no tiene un plan de ejecución asociado y la consulta del identificador del plan no devolverá un plan de presentación XML". http://technet.microsoft.com/en-us/library/cc645587.aspx

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.