SQL Server

Otimizando o desempenho de CPU do SQL Server

Zach Nichter

 

Visão geral:

  • Solução de problemas de desempenho do banco de dados
  • Exame de causas de hardware
  • Uso do PerfMon para controlar afunilamentos do banco de dados
  • Avaliação do desempenho de consultas

Solucionar problemas de desempenho em um sistema de banco de dados pode ser uma tarefa árdua. Saber onde procurar problemas é importante, mas é crucial saber por que o sistema reage dessa forma a uma determinada solicitação. Vários fatores podem afetar a utilização da CPU

em um servidor de banco de dados: compilação e recompilação de instruções SQL, índices ausentes, operações multithreaded, afunilamentos de disco, afunilamentos de memória, manutenções de rotina, atividades ETL (extração, transformação e carregamento) etc. A utilização da CPU não é algo ruim por si só – a CPU está lá justamente para realizar trabalhos. A chave para uma utilização íntegra da CPU é verificar se ela está mesmo dedicando seu tempo a processar o que você deseja que seja processado, e não desperdiçando ciclos com código mal otimizado ou hardware ineficiente.

Dois caminhos que levam ao mesmo lugar

Quando a visão é de um nível mais alto, há dois caminhos para identificar problemas de desempenho da CPU. O primeiro é examinar o desempenho de hardware do sistema, um exercício que ajuda a determinar onde procurar quando você passa ao segundo caminho, examinar a eficiência de consulta do servidor. Esse segundo caminho costuma ser mais eficiente na identificação de problemas de desempenho do SQL Server™. A menos que saiba exatamente onde estão os problemas de desempenho de consulta, você deve sempre começar com uma avaliação do desempenho do sistema. Ao final, você normalmente acaba usando os dois caminhos. Vejamos alguns aspectos básicos para que possamos examinar ambos os caminhos.

Estabelecendo a base

Hyperthreading

Hyperthreading é um tópico que vale a pena abordar um pouco mais por conta da forma com que ele afeta o SQL Server. Na verdade, o hyperthreading apresenta dois processadores lógicos ao sistema operacional para cada processador físico. Basicamente, ele concede tempo nos processadores físicos para que cada processador acabe sendo utilizado por completo. O site da Intel (intel.com/technology/platform-technology/hyper-threading/index.htm) oferece uma descrição bem mais detalhada de como funciona o hyperthreading.

Em sistemas com o SQL Server, como o DBMS, na verdade, processa de maneira extremamente eficiente seu próprio enfileiramento e threading no sistema operacional, o hyperthreading só serve para sobrecarregar as CPUs físicas em sistemas que já têm alta utilização de CPU. Quando o SQL Server coloca várias solicitações na fila para realizar o trabalho em vários agendadores, o sistema operacional precisa alternar continuamente o contexto dos threads nos processadores físicos para atender às solicitações feitas, mesmo que os dois processadores lógicos estejam acima do mesmo processador físico. Caso esteja vendo Alternâncias de Contexto/s superiores a 5.000 por processador físico, você deve considerar a desativação do hyperthreading no sistema e testar novamente o desempenho.

Em casos raros, aplicativos que enfrentam a alta utilização da CPU no SQL Server podem efetivamente usar o hyperthreading. Sempre teste os aplicativos em relação ao SQL Server com hyperthreading ativado e desativado, antes de implementar alterações nos sistemas de produção.

Um processador dual-core avançado superará facilmente a RAM de um computador, que, por sua vez, será mais rápido do que um dispositivo de armazenamento conectado. Uma boa CPU pode processar aproximadamente seis vezes a produtividade da memória DDR2 avançada atual e cerca de duas vezes a produtividade da memória DDR3 avançada. A produtividade de memória típica é mais de 10 vezes a das unidades de Fiber Channel mais rápidas. Já os discos rígidos só podem realizar um número finito de IOPS (operações de entrada/saída por segundo), um valor inteiramente limitado pelo número de buscas por segundo que uma unidade pode realizar. Para ser justo, não é comum que apenas uma unidade de armazenamento seja usada para atender a todas as necessidades de armazenamento em sistemas de bancos de dados corporativos. A maioria das configurações atuais utiliza SANs (redes de área de armazenamento) em servidores de bancos de dados corporativos ou grupos de RAID maiores capazes de anular ou minimizar o problema do processador de E/S do disco. O mais importante é se lembrar de que, independentemente de como seja a configuração, afunilamentos de disco e de memória podem afetar o desempenho dos processadores.

Por conta das diferenças na velocidade de E/S, recuperar dados do disco é muito mais caro do que recuperar dados da memória. Uma página de dados no SQL Server tem 8 KB. Uma extensão no SQL Server é formada por oito páginas de 8 KB, o que equivale a 64 KB. Isso é importante compreender porque quando o SQL Server solicita uma determinada página de dados, não se recupera apenas ela, mas também toda a extensão na qual a página de dados está. Há razões que efetivamente tornam o SQL Server mais econômico, mas eu não entrarei em detalhes aqui. Receber uma página de dados que já esteja armazenada no cache do pool de buffers, no pico do desempenho, deve durar menos de meio milissegundo; recuperar uma única extensão do disco deve levar entre 2 e 4 milissegundos em um ambiente ideal. Eu normalmente espero que a leitura de um subsistema de discos íntegro, com bom desempenho, demore de 4 a 10 milissegundos. Recuperar uma página de dados da memória costuma ser entre 4 e 20 vezes mais rápido do que receber uma página de dados do disco.

Quando solicita uma página de dados, o SQL Server verifica o cache de buffer na memória antes de procurá-la no subsistema de discos. Se a página de dados for encontrada no pool de buffers, o processador recuperará os dados e realizará o trabalho solicitado. Isso se chama falha de página simples. As falhas de página simples são ideais para o SQL Server porque os dados recuperados como parte de uma solicitação devem estar no cache de buffer para que sejam usados. Uma página de dados que não seja encontrada no cache de buffer deve ser recuperada no subsistema de discos do servidor. Quando o sistema operacional precisa recuperar a página de dados do disco, isso é conhecido como falha de página complexa.

Durante a correlação entre desempenho de memória, desempenho de disco e desempenho de CPU, um denominador comum nos ajuda a colocar tudo em uma só perspectiva: produtividade. Em termos nem tão científicos, produtividade é a avaliação de quantos dados é possível transmitir por um pipe limitado.

Caminho 1: desempenho do sistema

Há, de fato, alguns poucos métodos para determinar se um servidor tem um afunilamento de CPU, embora haja muitas causas possíveis para uma alta utilização de CPU. Alguns desses problemas podem ser controlados com PerfMon ou uma ferramenta de monitoramento de sistema semelhante, e outros são controlados usando SQL Profiler ou ferramentas similares. Outro método é usar comandos SQL via Query Analyzer ou SSMS (SQL Server Management Studio).

A filosofia que uso ao avaliar o desempenho de um sistema é "Começar pelo todo e ir se aprofundando". Obviamente, não é possível se concentrar em áreas com problemas até que você as identifique. Depois de avaliar a utilização geral da CPU usando uma ferramenta como PerfMon, você pode usá-la para observar alguns contadores de desempenho bastante simples e de fácil compreensão.

Um dos contadores de desempenho mais conhecidos é % Tempo de Processador; no PerfMon, ele é realçado assim que você abre a janela Adicionar Contador. % Tempo de Processador é o tempo no qual os processadores se mantêm ocupados com a execução do trabalho. A utilização dos processadores costuma ser considerada alta quando esse valor é igual a 80% ou mais para o pico do tempo de operação. É típico e esperado que você veja picos de até 100 por cento às vezes, mesmo quando o servidor não está operando com 80 por cento de utilização.

Outro contador que você deve examinar é Comprimento da fila de processador, que pode ser encontrado no objeto de desempenho Sistema no PerfMon. Comprimento da fila de processador mostra quantos threads estão aguardando a realização do trabalho na CPU. O SQL Server gerencia seu trabalho por meio de agendadores no mecanismo do banco de dados, em que ele coloca na fila e processa suas próprias solicitações. Por gerenciar seu próprio trabalho, o SQL Server só utilizará um único thread da CPU para cada processador lógico. Isso significa que deve haver um mínimo de threads aguardando na fila do processador para realizar o trabalho em um sistema dedicado ao SQL Server. Normalmente, não deve haver nada maior do que cinco vezes o número de processadores físicos em um SQL Server dedicado, mas eu considero mais de duas vezes algo já problemático. Nos servidores em que o DBMS compartilha um sistema com outros aplicativos, você desejará examinar isso com os contadores de desempenho % Tempo de Processador e Alternâncias de contexto/s (abordarei as alternâncias de contexto daqui a pouco) para determinar se os demais aplicativos ou DBMS precisam ser movidos para um servidor diferente.

Quando vejo o processador colocando na fila com uma utilização de CPU alta, eu observo os contadores Compilações/s e Recompilações/s no SQL Server: objeto de desempenho Estatísticas do SQL (consulte a Figura 1). Compilar e recompilar planos de consulta acrescentam à utilização da CPU de um sistema. Você deve ver valores próximos de zero referentes a Recompilações, mas observe as tendências nos sistemas para determinar de que forma o servidor normalmente se comporta e quantas compilações são normais. Nem sempre é possível evitar as recompilações, mas as consultas e os procedimentos armazenados podem ser otimizados para minimizá-las e reutilizar planos de consulta. Compare esses valores com as instruções SQL reais que chegam ao sistema por meio de Solicitações em Lote/s, também encontrado no SQL Server: objeto de desempenho Estatísticas do SQL. Caso as compilações e recompilações por segundo formem um alto percentual das solicitações em lote recebidas pelo sistema, essa é uma área que deve ser examinada. Em algumas situações, os desenvolvedores SQL talvez não compreendam como ou por que o código pode contribuir para com esses tipos de problemas de recurso do sistema. Ainda neste artigo eu darei algumas referências para ajudar você a minimizar esse tipo de atividade.

Figura 1 Selecionando os contadores a serem monitorados

Figura 1** Selecionando os contadores a serem monitorados **(Clique na imagem para aumentar a exibição)

Enquanto você estiver no PerfMon, verifique o contador de desempenho chamado Alternâncias de contexto/s (consulte a Figura 2). Esse contador informa quantas vezes os threads precisam ser retirados dos agendadores do sistema operacional (e não do SQL) a fim de realizar o trabalho para os demais threads em espera. As alternâncias de contexto costumam ser muito mais freqüentes em sistemas de bancos de dados compartilhados com outros aplicativos como IIS ou outros componentes do servidor de aplicativos do fornecedor. O limite que eu uso para Alternâncias de contexto/s é de aproximadamente 5 mil vezes o número de processadores no servidor. Esse valor também pode ser alto em sistemas que tenham o hyperthreading ativado e utilização da CPU entre moderada e alta. Quando a utilização da CPU e as alternâncias de contexto excedem regularmente seus limites, isso indica um afunilamento de CPU. Caso isso seja algo regular, você deve começar a planejar a compra de mais CPUs ou CPUs mais rápidas, em caso de desatualização do sistema. Para obter mais informações, consulte a barra lateral "Hyperthreading".

Figure 2 Contadores de desempenho a serem observados

Contador de desempenho Objeto de contador Limite Observações
% Tempo de Processador Processador > 80% As causas em potencial incluem pressão de memória, baixa reutilização do plano de consulta, consultas não otimizadas.
Alternâncias de contexto/s Sistema > 5 mil processadores As causas em potencial incluem os demais aplicativos no servidor, mais de uma instância de SQL Server em execução no mesmo servidor, hyperthreading ativado.
Comprimento da fila de processador Sistema > cinco processadores As causas em potencial incluem outros aplicativos no servidor, muitas compilações ou recompilações, mais de uma instância do SQL Server em execução no mesmo servidor.
Compilações/s SQLServer:Estatísticas do SQL Tendência Comparar com Solicitações em Lote/s
Recompilações/s SQLServer:Estatísticas do SQL Tendência Comparar com Solicitações em Lote/s
Solicitações em Lote/s SQLServer:Estatísticas do SQL Tendência Compare com Compilações e Recompilações por segundo.
Expectativa de Vida da Página SQLServer:Gerenciador de Buffer < 300 Potencial de pressão de memória.
Gravações Lentas/s SQLServer:Gerenciador de Buffer Tendência Potencial de muitas liberações do cache de dados ou pressão de memória.
Pontos de verificação/s SQLServer:Gerenciador de Buffer Tendência Avaliar pontos de verificação em relação a PLE e Gravações Lentas/s
Taxa de Acessos ao Cache: Planos SQL SQLServer:Cache de Planos < 70% Indica baixa reutilização do plano.
Taxa de Acessos ao Cache do Buffer SQLServer:Gerenciador de Buffer < 97% Potencial de pressão de memória.
       

O Gravador Lento do SQL Server (como ele é chamado no SQL Server 2000) ou o Monitor de Recursos (como ele é chamado no SQL Server 2005) é outra área a ser monitorada quando a utilização da CPU é alta. Liberar o buffer e os caches de procedimento pode acrescentar à hora da CPU por meio do thread de recurso chamado Monitor de Recursos. O Monitor de Recursos é um processo do SQL Server que determina as páginas a serem mantidas e as páginas a serem liberadas do pool de buffers para o disco. Todas as páginas no buffer e nos caches de procedimento são originalmente atribuídas a um custo que representa os recursos consumidos quando elas são colocadas no cache. Esse valor de custo será decrementado sempre que o Monitor de Recursos verificá-lo. Quando uma solicitação exige espaço em cache, as páginas são liberadas da memória com base no custo associado a cada uma delas; as páginas com os menores valores são as primeiras a serem liberadas. A atividade do Monitor de Recursos pode ser controlada por meio do contador de desempenho Gravações Lentas/s no SQL Server: Objeto Gerenciador de Buffer dentro do PerfMon. Você deve controlar essas tendências de valor para determinar o limite típico no sistema. Esse contador costuma ser examinado com os contadores Expectativa de Vida da Página e Pontos de verificação/s para determinar se há pressão de memória.

O contador PLE (Expectativa de Vida da Página) ajuda a determinar a pressão de memória. O contador PLE mostra por quanto tempo uma página de dados permanece no cache de buffer. O limite aceito pelo setor é de 300 segundos para esse contador. Tudo o que estiver abaixo de uma média de 300 segundos durante um período estendido informa você de que as páginas de dados estão sendo liberadas da memória com muita freqüência. Quando isso acontece, ele faz com que o Monitor de Recursos trabalhe mais, o que força mais atividades nos processadores. O contador PLE deve ser avaliado com o contador Páginas do Ponto de Verificação/s. Quando ocorre um ponto de verificação no sistema, as páginas de dados sujas no cache de buffer são liberadas para o disco, o que faz com que o valor PLE diminua. Como o processo Monitor de Recursos é o mecanismo que efetivamente libera essas páginas para o disco, durante esses pontos de verificação, você também deve ver o valor Gravações Lentas/s aumentar. Caso o valor PLE aumente imediatamente após a conclusão de um ponto de verificação, é possível ignorar esse sintoma temporário. Por outro lado, caso você ache que sempre está abaixo do limite de PLE, há uma chance muito boa de que essa memória adicional minimize os problemas e, ao mesmo tempo, libere alguns recursos novamente para a CPU. Todos esses contadores são encontrados no SQL Server: Objeto de desempenho Gerenciador de Buffer.

Caminho 2: desempenho de consultas

Controle SP

Durante o rastreamento do aplicativo do SQL Server, ele é familiarizado com os procedimentos armazenados usados no rastreamento. Usar a interface GUI (SQL Server Profiler) no rastreamento pode aumentar a carga do sistema em 15% a 25%. Caso seja possível usar procedimentos armazenados no rastreamento, isso pode cair pela metade.

Quando sei que há um afunilamento em algum lugar do meu sistema e eu desejo determinar quais são as instruções SQL atuais que estão causando problemas no meu servidor, eu executo a consulta abaixo. Essa consulta me ajuda a ter uma visão individual das instruções e dos recursos usados atualmente, bem como das instruções que precisam ser examinadas para aprimoramentos de desempenho. Para obter mais informações sobre as consultas SQL, consulte msdn2.microsoft.com/ms191006.aspx.

SELECT 
    substring(text,qs.statement_start_offset/2
        ,(CASE    
            WHEN qs.statement_end_offset = -1 THEN len(convert(nvarchar(max), text)) * 2 
            ELSE qs.statement_end_offset 
        END - qs.statement_start_offset)/2) 
    ,qs.plan_generation_num as recompiles
    ,qs.execution_count as execution_count
    ,qs.total_elapsed_time - qs.total_worker_time as total_wait_time
    ,qs.total_worker_time as cpu_time
    ,qs.total_logical_reads as reads
    ,qs.total_logical_writes as writes
FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
    LEFT JOIN sys.dm_exec_requests r 
        ON qs.sql_handle = r.sql_handle
ORDER BY 3 DESC

Os planos de consulta são avaliados, otimizados, compilados e colocados no cache de procedimento quando uma nova consulta é enviada para o SQL Server. Sempre que uma consulta é enviada para o servidor, o cache de procedimento é examinado para verificar se há uma correspondência entre um plano de consulta e uma solicitação. Se houver uma, o SQL Server criará um novo plano para ela, o que pode ser uma operação dispendiosa.

Algumas considerações sobre a otimização de CPU de T-SQL:

  • Reutilização do plano de consulta
  • Redução de compilações e recompilações
  • Classificação de operações
  • Junções incorretas
  • Índices não encontrados
  • Verificações de tabela/índice
  • Uso de funções em cláusulas SELECT e WHERE
  • Operações multithreaded

Então, coloquemos isso um pouco em perspectiva. O SQL Server normalmente recebe dados da memória e do disco, e não é muito comum trabalhar com apenas uma página de dados. Mais freqüentemente, você tem várias partes de um aplicativo funcionando em um registro, executando várias consultas menores ou unindo tabelas para fornecer uma visão completa dos dados relevantes. Em ambientes OLAP, os aplicativos podem receber milhões de linhas de uma ou duas tabelas para que seja possível consolidar, acumular e resumir dados de um relatório de vendas regional. Em situações como essas, o retorno dos dados pode ser medido em milissegundos se os dados estiverem na memória, mas esses milissegundos podem se transformar em minutos com a recuperação dos mesmos dados do disco, e não da RAM.

O primeiro exemplo é uma situação com um grande volume de transações e a reutilização do plano depende do aplicativo. A baixa reutilização do plano causa um grande número de compilações de instruções SQL, o que, por sua vez, resulta em um grande volume de processamento na CPU. No segundo exemplo, a grande reutilização de recursos do sistema pode causar um excesso de atividade da CPU do sistema, uma vez que os dados existentes devem ser constantemente liberados para o cache de buffer para dar espaço ao grande volume de novas páginas de dados.

Considere um sistema altamente transacional, em que uma instrução SQL como a mostrada abaixo é executada 2 mil vezes em um período de 15 minutos para poder recuperar as informações sobre a remessa de caixas. Sem a reutilização de um plano de consultas, hipoteticamente, você poderia ter um tempo de execução individual de aproximadamente 450 ms por instrução. Se o mesmo plano de consultas fosse usado depois da execução inicial, todas as consultas subseqüentes seriam possivelmente executadas em aproximadamente 2 ms, o que resulta em um tempo total de execução de cerca de 5 segundos.

USE SHIPPING_DIST01;
SELECT 
    Container_ID
    ,Carton_ID
    ,Product_ID
    ,ProductCount
    ,ModifiedDate
FROM Container.Carton
WHERE Carton_ID = 982350144;

A reutilização do plano de consulta é crítica para que haja o desempenho ideal em sistemas altamente transacionais e ela costuma ser obtida com a parametrização das consultas ou dos procedimentos armazenados. Aqui estão algumas fontes de informações excelentes sobre a reutilização do plano de consulta:

  • Problemas de compilação em lote, de recompilação e de cache no SQL Server 2005 (microsoft.com/technet/prodtechnol/sql/2005/recomp.mspx)
  • Otimizando procedimentos armazenados do SQL Server para evitar recompilações (sql-server-performance.com/rd_optimizing_sp_recompiles.asp)
  • Recompilação de consultas no SQL Server 2000 (msdn2.microsoft.com/aa902682.aspx)

Um lugar útil que conta com muitas informações são as DMVs (exibições de gerenciamento dinâmico) do SQL Server 2005. Quando a utilização da CPU é alta, há algumas DMVs que eu uso para me ajudar a determinar se a CPU está sendo utilizada corretamente ou não.

Uma das DMVs examinadas por mim é sys.dm_os_wait_stats, usada para fornecer DBAs com um meio de determinar cada tipo de recurso ou função usado pelo SQL Server, e ela mede o tempo durante o qual o sistema aguarda por conta desse recurso. Os contadores nessa DMV são cumulativos. Isso significa que, para ver claramente os recursos que poderiam afetar diferentes áreas do sistema, você primeiro precisará emitir um comando DBCC SQLPERF('sys.dm_os_wait_stats', CLEAR) para redefinir todos os contadores depois de examinar os dados em busca de algum problema pendente. A DMV sys.dm_os_wait_stats é o equivalente do comando SQLPERF(WAITSTATS) do DBCC de verificação da consistência do banco de dados no SQL Server 2000. É possível saber mais informações sobre os tipos diferentes de espera no SQL Server Books Online em msdn2.microsoft.com/ ms179984.aspx.

É importante saber que as esperas são típicas em um sistema, mesmo quando tudo está sendo executado em termos ideais. Você só precisa determinar se as esperas estão sendo afetadas por um afunilamento de CPU. As esperas de sinal devem ser as mínimas possíveis em relação ao tempo de espera geral. O tempo que um determinado recurso aguarda para que um recurso do processador pode ser determinado com a simples subtração do tempo de espera do sinal do tempo de espera total; esse valor não deve ser maior de que aproximadamente 20% do tempo de espera total.

A DMV sys.dm_exec_sessions mostra todas as sessões abertas no SQL Server. Essa DMV oferece uma exibição em alto nível do desempenho de cada sessão e todo o trabalho realizado por cada uma desde sua criação. Isso inclui o tempo total que a sessão perdeu esperando, a utilização da CPU total, o uso da memória e uma contagem das leituras e das gravações. A DMV também fornecerá a você o login, a hora do login, o computador host e o último momento em que a sessão enviou uma solicitação do SQL Server.

Usando a DMV sys.dm_exec_sessions, você poderá determinar apenas as sessões ativas; portanto, caso você esteja vendo uma alta utilização da CPU, esse é o primeiro local a ser observado. Examine as sessões que tenham uma alta contagem de CPU primeiro. Determine o aplicativo e o usuário que estão realizando o trabalho e comece a se aprofundar. Comparar sys.dm_exec_sessions com a DMV sys.dm_exec_requests pode oferecer grande parte das informações disponíveis por meio dos procedimentos armazenados sp_who e sp_who2. Caso relacione esses dados à DMF (função de gerenciamento dinâmico) sys.exec_sql_text usando a coluna sql_handle, você pode obter a consulta atualmente em execução da sessão. O trecho na Figura 3 mostra como integrar esses dados para ajudar a determinar o que realmente está acontecendo em um servidor.

Figure 3 Determinando atividade do servidor

SELECT es.session_id
    ,es.program_name
    ,es.login_name
    ,es.nt_user_name
    ,es.login_time
    ,es.host_name
    ,es.cpu_time
    ,es.total_scheduled_time
    ,es.total_elapsed_time
    ,es.memory_usage
    ,es.logical_reads
    ,es.reads
    ,es.writes
    ,st.text
FROM sys.dm_exec_sessions es
    LEFT JOIN sys.dm_exec_connections ec 
        ON es.session_id = ec.session_id
    LEFT JOIN sys.dm_exec_requests er
        ON es.session_id = er.session_id
    OUTER APPLY sys.dm_exec_sql_text (er.sql_handle) st
WHERE es.session_id > 50    -- < 50 system sessions
ORDER BY es.cpu_time DESC

Eu achei que essa instrução ajuda a determinar os aplicativos que precisam de atenção. Quando eu comparo CPU, memória, leituras, gravações e leituras lógicas de todas as sessões dentro de um aplicativo e determino que o recurso de CPU é muito maior do que os demais recursos utilizados, começo a me concentrar nessas instruções SQL.

Para controlar historicamente as instruções SQL de um aplicativo, eu uso os rastreamentos do SQL Server. É possível acessá-los por meio da ferramenta SQL Server Profiler ou dos procedimentos armazenados do sistema de rastreamento para ajudar a avaliar o que está acontecendo. (Consulte a barra lateral "Controle SP" para obter mais informações sobre o tópico.) O Profiler deve ser examinado em busca de instruções com alta utilização da CPU, bem como avisos de hash e de classificação, perdas de cache e outros sinalizadores vermelhos. Isso pode ajudar você a restringir instruções SQL específicas ou um período específico que tenha causado uma alta utilização do recurso. O Profiler é capaz de controlar coisas como o texto da instrução SQL, os planos de execução, a utilização da CPU, o uso da memória, as leituras lógicas, as gravações, o armazenamento em cache dos planos de consulta, as recompilações, as ejeções dos planos de consulta do cache, as perdas de cache, as verificações de tabela e índice, as estatísticas não encontradas e muitos outros eventos.

Depois de colher os dados dos procedimentos armazenados sp_trace ou do SQL Server Profiler, eu costumo usar um banco de dados, preenchido com dados de rastreamento após o fato ou com a configuração do rastreamento para gravar no banco de dados. Preencher o banco de dados após o fato pode ser feito usando a função do sistema do SQL Server chamada fn_trace_getinfo. O benefício dessa abordagem é que eu posso consultar e classificar os dados de várias formas para ver quais instruções SQL mais usaram a CPU ou tiveram mais leituras, contar quantas recompilações houve e muitas outras coisas. Eis um exemplo de como essa função é usada para carregar uma tabela com um arquivo de rastreamento do Profiler. O padrão determina que todos os arquivos deste rastreamento serão carregados na ordem em que foram criados:

SELECT * INTO trc_20070401
FROM fn_trace_gettable('S:\Mountpoints\TRC_20070401_1.trc', default);
GO

Conclusão

Como você viu, a alta utilização da CPU não necessariamente indica a existência de um afunilamento de CPU. A alta utilização da CPU talvez esteja escondendo vários outros afunilamentos de aplicativo ou de hardware também. Depois de identificar que você tem uma alta utilização da CPU, apesar dos demais contadores parecerem íntegros, é possível começar a procurar a causa dentro do sistema e isolar uma solução (seja a compra de mais CPUs ou a otimização do código SQL). E independentemente do que você faça, não desista! Com as dicas fornecidas neste artigo, com um pouco de prática e de pesquisa, a otimização da utilização da CPU no SQL Server é um plano de execução possível.

Zach Nichter é um profissional de SQL Server com mais de dez anos de experiência. Ele tem assumido várias funções de suporte do SQL Server, incluindo administrador de banco de dados, chefe de equipe, gerente e consultor. Atualmente, Zach trabalha na Levi Strauss & Co. como o arquiteto do banco de dados, enfocando o desempenho, o monitoramento, a arquitetura e outras iniciativas estratégicas. Além disso, Zach é autor do blog de vídeo em www.sqlcatch.com.

© 2008 Microsoft Corporation e CMP Media, LLC. Todos os direitos reservados. A reprodução parcial ou completa sem autorização é proibida..