Banco travando? Como achar queries lentas com pg_stat_statements
Descubra como rastrear gargalos de banco de dados em produção usando a extensão nativa pg_stat_statements do PostgreSQL sem prejudicar a performance.
Resumo
- A extensão pg_stat_statements coleta métricas agregadas de execução direto da memória do banco sem sobrecarregar o sistema
- Consultas lentas muitas vezes ocorrem por falta de índices adequados ou varreduras completas em tabelas massivas
- É possível identificar comandos SQL que mais consomem tempo de CPU correlacionando chamadas e tempo total de resposta
- A limpeza periódica das estatísticas acumuladas ajuda a isolar novos problemas após alterações no código da aplicação
- O monitoramento contínuo de consultas previne indisponibilidades severas em ambientes de produção com alto volume de acessos
Por que o banco de dados fica lento em produção
Quando uma aplicação começa a responder devagar, o gargalo quase sempre está escondido em uma consulta mal construída ao banco de dados. Em sistemas modernos, descobrir exatamente qual instrução SQL está consumindo toda a memória e o processador pode parecer como procurar uma agulha no palheiro. Na prática, isso significa que sem as ferramentas certas, desenvolvedores acabam adivinhando o problema em vez de diagnosticá-lo com dados reais de produção.
Para resolver esse desafio sem instalar softwares externos pesados, o ecossistema do PostgreSQL traz uma ferramenta nativa chamada pg_stat_statements. Ela funciona como um gravador de caixa-preta, registrando estatísticas detalhadas sobre cada comando executado pelo banco. Esse tipo de diagnóstico é essencial para complementar estratégias mais amplas de performance, como discutimos em nosso guia sobre como otimizar consultas no Postgres, garantindo que o sistema suporte picos de acesso sem travar.
O que é e como funciona o pg_stat_statements
O pg_stat_statements é um módulo integrado ao PostgreSQL que rastreia o planejamento e a execução de todas as consultas SQL que passam pelo servidor. Diferente de logs tradicionais que geram gigabytes de texto em disco, essa extensão mantém um resumo em memória RAM, agrupando consultas semelhantes e somando o tempo total que gastaram. Na prática, se a sua aplicação roda a mesma busca por ID cem vezes, a extensão agrupa tudo em uma única linha estatística com o tempo acumulado.
Antes de extrair dados úteis, é preciso garantir que a extensão esteja ativa no arquivo de configuração principal do banco, o postgresql.conf. Você deve adicionar o módulo na diretiva shared_preload_libraries e reiniciar o serviço do banco de dados. Essa etapa exige privilégios de administrador e uma breve janela de manutenção, pois o PostgreSQL precisa carregar a biblioteca assim que inicializa o sistema operacional.
Como habilitar e configurar a extensão no banco
Depois que o serviço do PostgreSQL é reiniciado com o parâmetro carregado, o próximo passo é criar a extensão de fato dentro do banco de dados específico que você deseja monitorar. Para isso, basta executar um comando simples de criação no terminal SQL. Na prática, isso significa que qualquer usuário com permissões adequadas pode rodar o comando e liberar o acesso às tabelas virtuais de métricas.
Para ativar a extensão e começar a coletar os dados de performance em tempo real, execute o seguinte comando no seu cliente de banco de dados favorito:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;Com a extensão instalada, o PostgreSQL cria uma visão no sistema chamada pg_stat_statements. É nela que você vai consultar o histórico consolidado de performance de todas as aplicações conectadas, permitindo cruzar dados de tempo de execução, número de linhas afetadas e quantidade de chamadas realizadas.
Como consultar as queries que mais consomem tempo
Com a ferramenta rodando e coletando dados, chegou o momento de analisar o comportamento real da aplicação em busca dos verdadeiros vilões da performance. Em vez de olhar apenas para o tempo de execução isolado de uma consulta, o segredo é ordenar os resultados pelo tempo total acumulado, que multiplica a lentidão individual pela frequência com que a consulta é chamada.
Para listar as dez consultas que mais consomem tempo de processamento no seu servidor de banco de dados, você pode utilizar uma consulta estruturada diretamente na visão do sistema. Execute o comando abaixo no terminal:
SELECT round(total_exec_time::numeric, 2) AS total_time_ms, calls, round(mean_exec_time::numeric, 2) AS avg_time_ms, queryFROM pg_stat_statementsORDER BY total_exec_time DESCLIMIT 10;Esse comando retorna uma lista clara contendo o tempo total gasto por cada instrução, quantas vezes ela foi chamada e a média de milissegundos por execução. Na prática, uma consulta rápida que roda milhões de vezes por dia vai aparecer no topo dessa lista muito antes de uma consulta extremamente pesada que roda apenas uma vez.
Interpretando os resultados e identificando gargalos
Ao analisar a lista gerada pela consulta anterior, preste muita atenção na coluna de chamadas combinada com o tempo médio. Se uma consulta simples de busca por usuário está demorando apenas vinte milissegundos, mas é chamada dez mil vezes por minuto, ela representa um gargalo crítico que drena os recursos do servidor. Nesses casos, adicionar um índice adequado no banco resolve o problema instantaneamente e alivia a pressão sobre a CPU.
Outro ponto importante é observar consultas que retornam muitas linhas mas utilizam poucos recursos por linha, indicando a falta de paginação ou filtros restritivos no código da aplicação. Diagnosticar esses comportamentos sob carga real é o que diferencia sistemas instáveis de arquiteturas resilientes prontas para escalar sem surpresas desagradáveis. Para complementar essa implementação em produção, vale conferir também nossas análises técnicas sobre Como testar o botão de ligar do notebook na bancada e Como isolar tráfego IoT criando uma VLAN no MikroTik.
Resetando as estatísticas e mantendo o monitoramento
Como o pg_stat_statements acumula dados continuamente desde a última reinicialização ou limpeza manual, métricas antigas podem mascarar problemas recentes causados por uma nova atualização de software. Para garantir que você está analisando apenas o comportamento atual do sistema, é recomendável zerar as estatísticas periodicamente ou após realizar deploys importantes na aplicação.
Para reiniciar o contador de estatísticas da extensão e começar uma nova coleta limpa, execute o comando de reset diretamente no banco:
SELECT pg_stat_statements_reset();Manter uma rotina de inspeção com essa ferramenta garante que a equipe de engenharia identifique degradações de performance antes que os usuários finais percebam lentidão. O monitoramento contínuo transforma a gestão de banco de dados de um esforço reativo de apagar incêndios em uma operação previsível e controlada.