- Desempenho do Processador x Desempenho do SQL Server – Parte 4
- Desempenho do Processador x Desempenho do SQL Server – Parte 3
- Desempenho do Processador x Desempenho do SQL Server – Parte 2
- Desempenho do Processador x Desempenho do SQL Server – Parte 1
Quando falamos de desempenho de processador, estamos falando de tempo, conforme já foi mostrado nos posts anteriores desta série. A conta é simples: Um processador mais rápido significa que executa instruções em menos tempo!
Mas como o tempo de CPU é transformado em uma porcentagem? Essa foi uma pergunta que me fizeram há anos: Quantos por cento significa esses tempos reportados nas DMVs do SQL Server? Eu fui atrás das respostas e isto gerou até um artigo que foi capa na SQL Magazine!
No SQL Server, a famosa sys.dm_exec_requests tem uma coluna chamada cpu_time. Você também conheceu o SET STATISTICS TIME, que traz informações sobre tempo de CPU gasto por queries em uma determinada sessão. E ainda há muitos outros lugares que reportam tempos de CPU dentro do SQL. Qual é a relação desses tempos com o percentual de CPU reportado no gerenciador de tarefas, por exemplo?
A resposta é simples, mas para entendê-la, vamos voltar um pouco pro sistema operacional!
Tempo Total de CPU
A métrica mais simples de entender, é o tempo total de CPU. Ela é apenas um valor, geralmente em microssegundos ou milissegundos, indicando por quanto tempo a CPU foi usada para completar uma operação, ou, quando a operação ainda não foi completada, quanto tempo de CPU já foi gasto até o momento. O SQL Server consegue mensurar o tempo de CPU gasto por suas operações graças ao Windows, que cuida de manter essa informação atualizada, e a fornece aos processos, quando eles precisam!
Basicamente, o Windows guarda as informações de tempo de CPU por thread. Uma thread representa uma sequência de instruções. Todo processo (programa em execução), tem pelo menos uma thread e com o SQL Server não é diferente. Cada thread pode executar em apenas uma CPU por vez (e uma CPU é capaz de rodar apenas uma thread), e o Windows é responsável por decidir qual thread vai rodar em qual CPU.
Sempre que o Windows coloca uma thread em uma CPU, ele periodicamente vai atualizando o tempo em que esta thread está rodando na CPU. Sendo assim, até que a thread seja encerrada, o Windows mantém um tempo total de CPU gasto para cada uma das threads existentes, de cada processo.
Com essa informação é possível que qualquer outro programa possa monitorar o consumo de CPU de qualquer operação. Por exemplo, para que o SQL Server saiba quanto tempo de CPU um comando gastou, ele poderia utilizar os seguintes passos:
- Obter o tempo total de CPU gasto até agora pela thread que vai rodar a query.
- Deixa a query rodar até o final
- Depois que a query rodar, basta subtrair o tempo total da thread, pelo tempo capturado no passo 1.
Por exemplo, vamos supor que o SQL Server vá rodar um comando SELECT. Para que este comando execute, uma thread (que dentro do SQL Server, ele chama de worker) já está associada com essa execução, então ele pode fazer o seguinte:
- Obter (do Windows) o tempo total de CPU que essa thread já gastou durante a vida dela. Suponha que seja 2000 millisegundos. Vamos chamar de TempoInicio = 2000
- Executa a query…
- Após a execução, obter novamente o tempo total e CPU que a thread gastou. Como a thread precisou rodar a query, certamente ela precisou entrar algumas vezes na CPU, aumentando o valor do seu tempo total de CPU. Suponha que tenha aumentado para 3000ms. Vamos chamar de TempoFim = 3000
- Agora é só calcular: TempoFim – TempoInicio = 3000 – 2000 = 1000ms
- Ou seja, a query gastou 1000ms de CPU!
Você vai ver que, utilizando esta mesma lógica, o SQL Server consegue registrar diversas informações de tempo de CPU, não somente para cada query que executa, mas para outros níveis como requests, sessões, tempo de compilação, por pool do Resource Governor, etc.
Todo esse exemplo foi considerando queries que rodam sem paralelismo. Com paralelismo, a conta tem apenas uma pequena variação, mas segue todos esse princípios. Veremos em outros posts da série.
Percentual de uso de CPU
O percentual de tempo de CPU já é um valor um pouquinho mais elaborado. Como é uma porcentagem, ele é um valor que se baseia em um total. Você já se perguntou quanto é o 100% de CPU?
Muitos podem pensar que o 100% significa estar usando a capacidade máxima da CPU. Mas esse percentual, não tem nada a ver com capacidade, até porquê ou há algo executando na CPU, ou não há.
Essa informação é calculada usando um intervalo de tempo previamente definido. A ideia é contabilizar quanto desse intervalo de tempo foi gasto processando algo na CPU. Por exemplo, se em um intervalo de 1 segundo, 400 ms foram gastos processando algo, então podemos dizer que a CPU esteve utilizada por 40% daquele intervalo de 1 segundo (400ms/1000ms).
E é assim que a maioria das ferramentas do Windows fazem: Elas coletam o tempo total de CPU de uma thread, e após um certo intervalo, coletam novamente. Então, para calcular quanto foi gasto de CPU nesse intervalo, elas apenas subtraem a segunda coleta pela primeira, e dividem pelo intervalo que se passou. A fórmula é essa:
(T2 – T1)/Intervalo
Onde T2, é o tempo total de CPU da segunda coleta, T1 é o da primeira, e Intervalo é tempo que se passou.
Ou seja, uma thread que gaste 100% de CPU, significa que durante todo o intervalo que se passou, ela não saiu da CPU. Geralmente, esse intervalo é de 1 segundo, sendo que a maioria das ferramentas de monitoramento permite que você altere este valor.
Repare a diferença entre total de cpu, e percentual de utilização de CPU. O total de cpu é um valor acumulado que representa tudo o que um recurso (thread, query, request, sessão, etc.) gastou durante toda sua vida. Já o percentual de uso de CPU é um valor relativo, indicando o uso de CPU em um dado momento no tempo.
Tempo de CPU x Percentual de CPU
Isso cria situações interessantes com as quais você pode se deparar: Por exemplo, imagine uma query que tenha gasto 2 segundos para executar na CPU. Esse é o tempo total de CPU. Dependendo de diversos fatores, ela pode ter ocasionado vários padrões de percentual uso de CPU:
Exemplo 1
- Entre o intervalo 1 e 2, gastou 500 ms de CPU, causando 50% de uso
- Entre o intervalo 2 e 3 não gastou nada (por esperar disco por exemplo), ocasionando 0% de CPU
- Entre o intervalo 3 e 4, gastou 1 segundo, ocasionando 100%
- Entre o intervalo 4 e 5, não gastou nada (devido a locks, por exemplo), ocasionando 0% de CPU
- Entre o valor 5 e 6, ter gasto mais 500ms, ocasionando 50%
Exemplo 2
- Entre o intervalo 1 e 2, gastou 700ms, ocasionando 70% de uso
- Entre o intervalo 2 e 3, gastou 1s, ocasionando 100% de uso
- Entre o intervalo 3 e 4, e 4 e 5, gastou nada, ocasionando 0%
- Entre o intervalo 5 e 6, gastou 300ms, ocasionando 30% de uso
Exemplo 3
- Entre o intervalo 1 e 2, gastou nada (0%)
- Entre o intervalo 2 e 3, gastou 1s (100%)
- Entre o intervalo 2 e 3, gastou 1s (100%)
Perceba como a mesma query, com o mesmo tempo total de CPU, pode apresentar diferentes padrões de percentual de utilização, devido a teoria por detrás destes conceitos! Isso nos leva a uma terceira definição de tempo que está envolvido nisso tudo: O tempo de duração! O tempo de duração (elapsed time) é o tempo total gasto para executar a query, incluindo o tempo de CPU e o tempo de espera.
Por exemplo, no exemplo 1 e 2, a query teve duração de 6 segundos, desses 6, 2 segundos foram gastos com CPU! Já no exemplo 3, a duração foi de 3 segundos, gastando os mesmos 2 segundosde CPU.
É por esse simples motivo, que o SQL Server reporta tempos completamente diferentes e que as vezes não fazem sentido algum quando você compara com a porcentagem reportada no Gerenciador de Tarefas. Na maior parte das informações fornecidas pelo SQL Server, ele está falando de “tempo total de CPU” e não de “percentual de utilização”. O tempo total de CPU é um acumulado durante toda a operação, enquanto que o percentual de utilização é baseado em determinado momento no tempo. Então, não tem como você dizer quantos por cento foi gasto por uma query que gastou 2 segundos CPU no passado. Você precisaria ter capturado isso no momento em que ela foi executada.
O SQL Server fornece informações de consumo de CPU em vários níveis, como por query, por sessão, por requests, etc. Ao longo de outros posts desta série, iremos explorar mais estes conceitos e observar com alguns exemplos práticos como podemos utilizá-los para fazer uma melhor análise do consumo de CPU no SQL Server!
—
E se você quer aprender mais sobre SQL Server e o Windows, não deixe de fazer o curso Fundamentos de Windows para DBA SQL Server – Módulo 1! Tem várias perguntas pra testar seu conhecimento, certificado de conclusão, e mais de 30 minutos FREE sobre algumas ferramentas que todo usuário do Windows precisa conhecer! Confira em https://cursos.fabriciolima.net e enxergue novas formas de administrar seu ambiente SQL!
DBA Team Leader na Power Tuning
Comments ( 5 )