Por que eu NÃO usaria a opção SQL Server "otimizar para cargas de trabalho ad hoc"?

49

Estive lendo ótimos artigos sobre Kimberly Tripp, como este: cache do plano do SQL Server, como este: http://www.sqlskills.com/blogs/kimberly/plan-cache-and-optimizing-for-adhoc-workloads/

Por que existe uma opção para "otimizar cargas de trabalho ad hoc"? Isso não deveria estar sempre ativado? Se os desenvolvedores estão usando SQL ad-hoc ou não, por que você não teria essa opção ativada em todas as instâncias que a suportam (SQL 2008+), reduzindo assim o inchaço do cache?

SomeGuy
fonte

Respostas:

45

A equipe de desenvolvimento do SQL Server trabalha com o princípio da menor surpresa - portanto, o SQL Server geralmente tem novos recursos desabilitados, a fim de manter o comportamento das versões anteriores.

Sim, otimizar para cargas de trabalho ad-hoc é excelente para reduzir o inchaço do cache do plano - mas sempre teste-o primeiro!

[Editar: Kalen Delaney conta uma anedota interessante de que ela perguntou a um de seus amigos de engenheiro da Microsoft se haveria circunstâncias em que não seria apropriado permitir isso. Ele volta alguns dias depois para dizer - imagine um aplicativo que tenha MUITAS consultas diferentes, e cada consulta execute exatamente duas vezes no total. Então pode ser inapropriado. Basta dizer que não há muitos aplicativos assim!]

[Editar: se a maioria das suas consultas for executada mais de uma vez (não exatamente duas vezes); provavelmente seria inapropriado. A regra geral seria ativá-lo se houver muitas consultas ad-hoc de uso único no banco de dados; no entanto, ainda não existem muitos aplicativos como esse.]

Peter Schofield
fonte
9
Os novos recursos do +1 são muito, muito raramente ativados por padrão. Não consigo realmente pensar em boas razões para não ativar esse recurso específico - na pior das hipóteses, todas as suas consultas são de uso único e não se beneficiariam do cache de qualquer maneira.
Aaron Bertrand
11
Esta é uma resposta "segura", baseada no senso comum e não aborda a questão. O solicitante deseja saber especificamente o caso de uso para quando NÃO ativar esse recurso, é melhor.
MikeTeeVee
2
MikeTeeVee - pode ser uma resposta segura, mas esse é um desses recursos em que eu realmente não consigo pensar em um motivo para não ativá-lo. Como é tão incrível, eu só queria explicar por que ele estava desativado por padrão!
22413 Peter Schofield
21

Abaixo está um pequeno código que ajudará você a decidir se "alternar a otimização para cargas de trabalho ad hoc ON / OFF" será benéfico ou não. Normalmente, verificamos isso como parte de nossa verificação de integridade para servidores internos e clientes.

É a opção mais segura a ser ativada e é bem descrita por Brad aqui e por Glenn Berry aqui .

--- 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
Kin Shah
fonte
7

Pense em um servidor de produção que atenda apenas 5 consultas diferentes, mas vários milhares delas por segundo. Você é a equipe de desenvolvimento do Microsoft SQL Server. Você vai mexer no cache do plano. Você ativa esse comportamento por padrão, quando sabe que alguns de seus maiores e mais críticos clientes (por exemplo, a implementação interna da SAP da Microsoft) trabalham no mesmo campus e usam a mesma lanchonete que você?

Stu
fonte
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Paul White
7

Ao ativar a opção " Otimizar para cargas de trabalho ad hoc ", você fará com que as consultas ad-hoc executadas pela segunda vez sejam tão lentas quanto a primeira, porque você estará compilando um plano de execução e puxando os mesmos dados ( sem ele armazenado em cache) essas duas primeiras vezes.
Isso pode não ser um grande problema, mas você notará isso ao testar consultas.
Então, o que acontece agora, sem essa opção ativada e um cache cheio de consultas pontuais ad-hoc?

O algoritmo de gerenciamento de cache:

Quando esse recurso de otimização foi introduzido, o algoritmo de gerenciamento de cache também foi atualizado.
O artigo de Kimberly Tripp também faz referência ao post de Kalen Delaney sobre essa alteração no algoritmo.
Ela explica melhor:

A alteração realmente calcula um tamanho de cache do plano no qual o SQL Server reconhece que há pressão de memória e começará a remover os planos do cache. Os planos a serem removidos são os planos baratos que não foram reutilizados, e isso é uma BOA COISA.

Isso significa que esses planos irritantes de um cronômetro serão os primeiros a serem liberados quando você precisar liberar recursos.

Então agora a questão se torna:

    " Por que precisamos de 'Otimizar para Ad Hoc cargas de trabalho' quando SQL Server cuida de remover planos não utilizados quando necessário? "

Minha resposta para isso é, se você tem regularmente uma s-tonelada de grande quantidade de geração de dinâmicas-sql de anúncio não parametrizado consultas -hoc, faz todo o sentido ativar esse recurso.
Você deseja evitar sobrecarregar os recursos do sistema, de modo a forçar a remoção de dados em cache / plano em cache após o uso do espaço máximo de memória em cache.

Como sei quando preciso ativar isso?

Aqui está uma consulta que escrevi para mostrar quantos planos Ad-Hoc você atualmente armazenou em cache e quanto espaço em disco eles estão consumindo (os resultados serão alterados ao longo do dia - teste-o durante um período de carga pesada):

--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: insira a descrição da imagem aqui

Não vou dizer " Quando você tiver X MB " ou " Se X% do seu Ad Hoc for de uso único " para ativar isso.
Não afeta Sprocs, Disparadores, Exibições ou SQL Parametrizado / Preparado - apenas as consultas Ad-Hoc.
Minha recomendação pessoal é apenas ativar o ambiente Prod, mas considere deixá-lo no ambiente Dev.
Digo isso apenas para o Dev, porque se você está otimizando uma consulta que leva um minuto ou mais para ser executada, não deseja executá-la três vezes antes de ver a rapidez com que ela será armazenada em cache - a cada uma vez que você o edita para encontrar o melhor design de otimização.
Se seu trabalho não envolve fazer isso o dia todo, fique louco e peça ao seu DBA para ativá-lo em qualquer lugar.

MikeTeeVee
fonte
0

"Por que NÃO devo usar ...." No decorrer de algumas investigações de desempenho, retirar os planos do cache do plano quase em tempo real, enquanto observa a utilização dos recursos, pode ser muito útil. A opção "Otimizar para cargas de trabalho ad-hoc" pode atrapalhar isso, pois os planos de stub ad-hoc não retornarão um plano ao consultar o cache. Em um caso como esse, se a consulta e o plano não puderem ser identificados, a configuração poderá ser ativada e desativada novamente para fins de investigação. Observe que uma alteração na configuração efetua consultas compiladas a partir desse ponto. Além disso, sempre que alterar uma propriedade 'server', verifique uma instância que não seja de produto na mesma versão para verificar se a alteração liberará ou não o cache do plano. Eu pessoalmente odeio ser surpreendido por isso. (Por exemplo, alterar maxdop no nível do servidor normalmente libera o cache do plano,

"O stub do plano compilado não possui um plano de execução associado e a consulta do identificador do plano não retornará um XML Showplan." http://technet.microsoft.com/en-us/library/cc645587.aspx

sql_handle
fonte