Qual o impacto das compilações SQL no desempenho do SQL Server?

20

Estou criando um perfil de uma instância de um SQL Server 2005 e, através da SQLServer:SQL Statistics - SQL Compilations/secmétrica do PerfMon , vejo que a média é de aproximadamente 170.

Peguei o SQL Profiler e procurei eventos SP: Compile ou SQL: Compile. Aparentemente, eles não existem. Eu encontrei Stored Procedure/SP:Recompilee TSQL/SQL:StmtRecompileeventos. A quantidade de dados que vejo no Profiler sugere que esses são os eventos errados a serem observados, embora não tenha certeza.

Então minhas perguntas. As respostas para qualquer uma delas seriam ótimas.

  1. Como posso ver o que exatamente está compilando no SQL Server?
  2. Escolhi as métricas erradas para analisar? No Perfmon ou no SQL Profiler?
  3. Com relação a Stored Procedure/SP:Recompilee TSQL/SQL:StmtRecompileeventos no SQL Profiler ... eles não incluem a métrica Duração. Como posso avaliar o impacto desses eventos no sistema, se eles não fornecem uma maneira de ver o impacto do tempo no sistema.
AngryHacker
fonte

Respostas:

33

Compilações SQL / s é uma boa métrica, mas somente quando associado a Solicitações em lote / s . Por si só, compilações por segundo realmente não dizem muito.

Você está vendo 170. Se a quantidade de solicitações em lote por segundo for de apenas 200 (um pouco exagerado para o efeito), então sim, você precisará se aprofundar na causa (provavelmente um uso excessivo de consultas ad hoc e planos de uso único). Mas se o número de solicitações em lote por segundo estiver medindo cerca de 5000, então 170 compilações por segundo não serão ruins. É uma regra geral prática que as compilações / s devem ser de 10% ou menos do que o total de solicitações em lote / s .

Se você realmente deseja detalhar o que está sendo armazenado em cache, execute a seguinte consulta que utiliza as DMVs apropriadas:

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 obter todos os planos de uso único (uma contagem):

;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 obter uma proporção de quantos planos de contagem de uso único você comparou a todos os planos em cache:

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

Quanto às durações capturadas por meio de um rastreamento do SQL Server, ele não está disponível para os eventos Recompilar. Não é tão significativo ver a duração ou a dor que a compilação do plano está causando, pois não há muito o que fazer em uma situação caso a caso. A solução é tentar limitar compilações e recompilações através da reutilização do plano (consultas parametrizadas, procedimentos armazenados, etc.).

Thomas Stringer
fonte
9

Existem três contadores relevantes que devem ser registrados usando o PerfMon (ou outra solução de terceiros). O ponto principal é registrar essas estatísticas de alguma forma.

  • Estatísticas SQL \ Solicitações em lote / s
  • Estatísticas SQL \ Compilações SQL / s
  • Estatísticas SQL \ Recompilações SQL / s

Como Thomas Stringer mencionou , é bom ficar de olho na proporção de compilações / solicitação de lote. Obviamente, quanto menor, melhor, mas existem apenas diretrizes para o que é "bom" e somente você pode decidir o que é aceitável. A quantidade absoluta de ganho de desempenho que você verá ao reduzir o número de compilações depende de muitos fatores.

Também gosto de analisar a proporção de recompilações / compilação , para ter uma noção da quantidade de reutilização do plano de consulta. Mais uma vez, menor é melhor. Nesse caso, no entanto, você deseja que as recompilações ocorram no sistema à medida que as estatísticas mudam (se o banco de dados for somente leitura e você tiver recompilações ... algo pode estar errado). Assim como eu disse anteriormente, existem apenas diretrizes para o que é "bom".

O que você realmente deseja fazer é direcionar esses números ao longo do tempo. Portanto, se você observar um grande aumento em qualquer uma das proporções, algo foi implantado que não está usando os planos de consulta corretamente (idealmente, isso é capturado durante o teste) - use o Shark's consultas de análise para encontrar os culpados. Além disso, aqui está um para encontrar consultas frequentemente recompiladas:

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

Se você também estiver gravando estatísticas para uso da CPU, todas as estatísticas poderão ser correlacionadas para descobrir o quanto dói e o quanto suas correções ajudam. Na prática, descobri que mesmo uma única estratégia ruim de plano de consulta em um núcleo principal pode trazer um servidor de joelhos; obviamente YMMV.

Jon Seigel
fonte