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](https://i.stack.imgur.com/Kmt5b.png)
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.