AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 63381
Accepted
DanM
DanM
Asked: 2014-04-17 15:46:28 +0800 CST2014-04-17 15:46:28 +0800 CST 2014-04-17 15:46:28 +0800 CST

Estatísticas de espera intermitentes de RESOURCE_SEMAPHORE_QUERY_COMPILE

  • 772

Estou tentando solucionar alguns picos de CPU intermitentes que estamos testemunhando em um de nossos SQL Servers de produção. Estamos executando o SQL Server 2008 R2 Standard Edition com 28 GB de RAM e 4 núcleos de CPU. Quando isso acontece, notamos um grande número de esperas RESOURCE_SEMAPHORE_QUERY_COMPILER, que duram cerca de um ou dois minutos e depois param, fazendo com que o uso da CPU volte ao normal.

Depois de pesquisar isso, entendo que isso normalmente é causado pela compilação de muitos planos de execução não reutilizáveis, para os quais estamos trabalhando atualmente em alterações em nosso aplicativo.

Esse comportamento também pode ser acionado por remoções de cache do plano devido à pressão de memória? Se sim, como eu verificaria isso? Estou tentando ver se há algum remédio de curto prazo que possamos fazer, como atualizar a RAM do servidor, até implantarmos nossas correções de aplicativos. A única outra opção de curto prazo em que consigo pensar é mover alguns de nossos bancos de dados mais ocupados para um servidor diferente.

sql-server wait-types
  • 2 2 respostas
  • 1860 Views

2 respostas

  • Voted
  1. Best Answer
    Aaron Bertrand
    2014-04-18T06:17:12+08:002014-04-18T06:17:12+08:00

    Acredito que você verá esse sintoma se tiver MUITOS planos de consulta grandes que estão lutando por memória para compilar (isso tem muito pouco a ver com a execução da consulta em si). Para acertar isso, suspeito que você esteja usando um ORM ou algum tipo de aplicativo que gere muitas consultas exclusivas, mas relativamente complexas. O SQL Server pode estar sob pressão de memória devido a coisas como grandes operações de consulta, mas, pensando bem, é mais provável que seu sistema esteja configurado com muito menos memória do que precisa (ou nunca há memória suficiente para satisfazer todas as consultas que você 're tentando compilar, ou há outros processos na caixa que estão roubando memória do SQL Server).

    Você pode dar uma olhada no que o SQL Server está configurado usando:

    EXEC sp_configure 'max server memory';    -- max configured in MB
    
    SELECT counter_name, cntr_value
      FROM sys.dm_os_performance_counters
      WHERE counter_name IN
      (
        'Total Server Memory (KB)',    -- max currently granted
        'Target Server Memory (KB)'    -- how much SQL Server wished it had
      );
    

    Você pode identificar os planos em cache que exigiram mais memória de compilação com a seguinte consulta de Jonathan Kehayias , ligeiramente adaptada:

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
    
    ;WITH XMLNAMESPACES (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
    SELECT TOP (10) CompileTime_ms, CompileCPU_ms, CompileMemory_KB,
      qs.execution_count,
      qs.total_elapsed_time/1000.0 AS duration_ms,
      qs.total_worker_time/1000.0 as cputime_ms,
      (qs.total_elapsed_time/qs.execution_count)/1000.0 AS avg_duration_ms,
      (qs.total_worker_time/qs.execution_count)/1000.0 AS avg_cputime_ms,
      qs.max_elapsed_time/1000.0 AS max_duration_ms,
      qs.max_worker_time/1000.0 AS max_cputime_ms,
      SUBSTRING(st.text, (qs.statement_start_offset / 2) + 1,
        (CASE qs.statement_end_offset
          WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset
         END - qs.statement_start_offset) / 2 + 1) AS StmtText,
      query_hash, query_plan_hash
    FROM
    (
      SELECT 
        c.value('xs:hexBinary(substring((@QueryHash)[1],3))', 'varbinary(max)') AS QueryHash,
        c.value('xs:hexBinary(substring((@QueryPlanHash)[1],3))', 'varbinary(max)') AS QueryPlanHash,
        c.value('(QueryPlan/@CompileTime)[1]', 'int') AS CompileTime_ms,
        c.value('(QueryPlan/@CompileCPU)[1]', 'int') AS CompileCPU_ms,
        c.value('(QueryPlan/@CompileMemory)[1]', 'int') AS CompileMemory_KB,
        qp.query_plan
    FROM sys.dm_exec_cached_plans AS cp
    CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS qp
    CROSS APPLY qp.query_plan.nodes('ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple') AS n(c)
    ) AS tab
    JOIN sys.dm_exec_query_stats AS qs ON tab.QueryHash = qs.query_hash
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
    ORDER BY CompileMemory_KB DESC
    OPTION (RECOMPILE, MAXDOP 1);
    

    Você pode ver como o cache do plano está sendo usado com o seguinte:

    SELECT objtype, cacheobjtype,
        AVG(size_in_bytes*1.0)/1024.0/1024.0,
        MAX(size_in_bytes)/1024.0/1024.0,
        SUM(size_in_bytes)/1024.0/1024.0,
        COUNT(*)
    FROM sys.dm_exec_cached_plans
    GROUP BY GROUPING SETS ((),(objtype, cacheobjtype))
    ORDER BY objtype, cacheobjtype;
    

    Quando você estiver enfrentando altas esperas de semáforo, verifique se esses resultados de consulta variam significativamente durante a atividade "normal":

    SELECT resource_semaphore_id, -- 0 = regular, 1 = "small query"
      pool_id,
      available_memory_kb,
      total_memory_kb,
      target_memory_kb
    FROM sys.dm_exec_query_resource_semaphores;
    
    SELECT StmtText = SUBSTRING(st.[text], (qs.statement_start_offset / 2) + 1,
            (CASE qs.statement_end_offset
              WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset
             END - qs.statement_start_offset) / 2 + 1),
      r.start_time, r.[status], DB_NAME(r.database_id), r.wait_type, 
      r.last_wait_type, r.total_elapsed_time, r.granted_query_memory,
      m.requested_memory_kb, m.granted_memory_kb, m.required_memory_kb,
      m.used_memory_kb
    FROM sys.dm_exec_requests AS r
    INNER JOIN sys.dm_exec_query_stats AS qs
    ON r.plan_handle = qs.plan_handle
    INNER JOIN sys.dm_exec_query_memory_grants AS m
    ON r.request_id = m.request_id
    AND r.plan_handle = m.plan_handle
    CROSS APPLY sys.dm_exec_sql_text(r.plan_handle) AS st;
    

    E você também pode querer ver como a memória é distribuída:

    DBCC MEMORYSTATUS;
    

    E há algumas boas informações aqui sobre por que você pode estar vendo um grande número de compilações/recompilações (o que contribuirá para essa espera):

    http://technet.microsoft.com/en-us/library/ee343986(v=sql.100).aspx
    
    http://technet.microsoft.com/en-us/library/cc293620.aspx
    

    Você pode verificar se há altas contagens de compilação/recompilação usando os seguintes contadores:

    SELECT counter_name, cntr_value
      FROM sys.dm_os_performance_counters
      WHERE counter_name IN 
      (
        'SQL Compilations/sec',
        'SQL Re-Compilations/sec'
      );
    

    E você pode verificar se há pressão de memória interna levando a despejos - contadores diferentes de zero aqui indicam que algo não é bom está acontecendo com o cache do plano:

    SELECT * FROM sys.dm_os_memory_cache_clock_hands 
      WHERE [type] IN (N'CACHESTORE_SQLCP', N'CACHESTORE_OBJCP');
    

    OBSERVAÇÃO A maioria dessas métricas não tem uma mágica "oh meu Deus, preciso entrar em pânico ou fazer alguma coisa!" limite. O que você precisa fazer é fazer medições durante a atividade normal do sistema e determinar onde estão esses limites para seu hardware, configuração e carga de trabalho. Quando você entra em pânico , faça alguma coisa é quando duas condições são verdadeiras:

    1. as métricas variam significativamente dos valores normais; e,
    2. na verdade, há um problema de desempenho ocorrendo (como picos de CPU) - mas apenas se eles estiverem realmente interferindo em alguma coisa. Além de ver o aumento das CPUs, você está vendo algum outro sintoma? Em outras palavras, o pico é o sintoma ou o pico está causando outros sintomas? Os usuários do sistema perceberiam? Muita gente sempre vai atrás do consumidor que espera mais alto, simplesmente porque é o mais alto. Algo sempre será o maior consumidor de espera - você deve saber que está variando o suficiente da atividade normal para indicar um problema ou alguma mudança significativa.

    Optimize for ad hoc workloadsé uma ótima configuração para 99% das cargas de trabalho existentes, mas não será muito útil para reduzir os custos de compilação - visa reduzir o inchaço do cache do plano, impedindo que um plano de uso único armazene todo o plano até que seja executado duas vezes . Mesmo quando você armazena apenas o stub no cache do plano, ainda precisa compilar o plano completo para a execução da consulta. Talvez o que @Kahn quisesse recomendar fosse definir a parametrização no nível do banco de dados como forçada , o que potencialmente fornecerá uma melhor reutilização do plano (mas realmente depende de quão exclusivas são todas essas consultas de alto custo).

    Também algumas boas informações neste white paper sobre armazenamento em cache e compilação de planos.

    • 7
  2. Kahn
    2014-04-17T21:57:03+08:002014-04-17T21:57:03+08:00

    De longe, o motivo mais comum pelo qual vi essas esperas aparecerem é resultado de índices fragmentados ou insuficientes e estatísticas que têm tamanho de amostra insuficiente ou são obsoletas. Isso resulta em verificações maciças de tabelas completas sobrecarregando toda a memória, o que, por sua vez, produz um sintoma que costumamos ver como RESOURCE_SEMAPHORE_QUERY_COMPILE.

    A maneira mais fácil de verificar isso é verificar se as consultas executam varreduras completas de tabela/índice, quando deveriam estar fazendo buscas de índice. Se você tiver uma consulta de problema com a qual pode reproduzir o problema - torna-se muito fácil diagnosticar e corrigir isso.

    Eu verificaria os índices nas tabelas afetadas por essas consultas problemáticas - ou seja. verifique a fragmentação do índice, possíveis índices filtrados que não são usados, índices ausentes que você pode querer criar, etc. Além disso, atualize suas estatísticas com FULLSCAN o mais rápido possível.

    Um bom ponto a lembrar é que sua tabela de problemas pode não ser a única que precisa disso. Por exemplo, se você tem uma consulta que busca dados de 10 tabelas, o planejador de execução pode ocasionalmente mostrar que não está usando o índice da tabela 1, mas quando você verifica o índice da tabela 1, na verdade está ok. O planejador de consulta pode resolver buscar dados na tabela 1 com uma varredura completa da tabela corretamente, porque um índice com falha/insuficiente na tabela 7, por exemplo, retornou tantos dados que esta seria a opção mais rápida. Portanto, diagnosticar isso às vezes pode ser complicado.

    Além disso, se você tiver muitas consultas code-behind com apenas algumas alterações nos valores das variáveis, por exemplo, convém verificar a ativação da otimização para cargas de trabalho ad hoc . Basicamente, o que ele faz é armazenar um esboço do plano compilado em vez do plano inteiro, economizando recursos quando você nunca obtém exatamente os mesmos planos todas as vezes.

    • -1

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve