pg_stat_statements
pg_stat_statements rastreia texto de consulta normalizado com contagem de chamadas, tempo total, linhas e I/O. Ele responde quais consultas consomem mais tempo do banco de dados, não qual execução única foi mais lenta. Habilite em todos os clusters PostgreSQL 18.4 de produção e reinicie as estatísticas após grandes lançamentos para obter linhas de base limpas.
Receita
-- Habilitar (postgresql.conf)
-- shared_preload_libraries = 'pg_stat_statements'
-- pg_stat_statements.track = all
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- Consultas principais por tempo total
SELECT calls,
round(total_exec_time::numeric, 2) AS total_ms,
round(mean_exec_time::numeric, 2) AS mean_ms,
rows,
left(query, 100) AS query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;Quando usar isso:
- Regressão de latência sem causa de infraestrutura óbvia
- Sprints de ajuste de índice priorizando
total_exec_timealto - Verificação pós-implantação comparando impressões digitais de consulta
Exemplo de Trabalho
Encontre regressões e vincule estatísticas a EXPLAIN.
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
-- Pesos pesados das últimas 24h de estatísticas cumulativas (desde a reinicialização)
SELECT queryid,
calls,
round(total_exec_time::numeric, 1) AS total_ms,
round((100 * total_exec_time / sum(total_exec_time) OVER ())::numeric, 2) AS pct_db_time,
shared_blks_read,
shared_blks_hit,
left(query, 120) AS query
FROM pg_stat_statements
WHERE dbid = (SELECT oid FROM pg_database WHERE datname = current_database())
ORDER BY total_exec_time DESC
LIMIT 15;
-- Reiniciar após a linha de base da implantação (superusuário)
-- SELECT pg_stat_statements_reset();
-- Exemplo EXPLAIN no texto de consulta pesado dos logs do aplicativo correspondendo a queryid
EXPLAIN (ANALYZE, BUFFERS)
SELECT o.id, o.total
FROM orders o
WHERE o.customer_id = $1
AND o.created_at > now() - interval '30 days';O que isso demonstra:
total_exec_timeclassifica o impacto da carga de trabalho melhor do que linhas de log lentas únicasqueryidcorrelaciona consultas ORM com estatísticas do planejador- A proporção de leitura/acerto de buffer indica gargalos de cache vs I/O
- Emparelhe com
EXPLAIN (ANALYZE, BUFFERS)em parâmetros representativos
Mergulho Profundo
Colunas Chave
| Coluna | Uso |
|---|---|
calls | Frequência |
total_exec_time | Tempo total de banco de dados consumido |
mean_exec_time | Média por chamada (observe outliers vs volume) |
rows | Linhas retornadas/afetadas por média de chamada |
shared_blks_read | Leituras de disco (alto = cache miss ou varredura sequencial) |
queryid | Impressão digital estável dentro da versão principal |
Configuração
SHOW shared_preload_libraries;
SHOW pg_stat_statements.max;
SHOW pg_stat_statements.track; -- top, all, noneUse track = all em aplicativos com uso intensivo de PL/pgSQL se precisar de instruções aninhadas.
Postgres Gerenciado
RDS e Cloud SQL oferecem pg_stat_statements como uma extensão permitida. O grupo de parâmetros pode exigir uma reinicialização de shared_preload_libraries.
Armadilhas
- Não em shared_preload_libraries - a extensão é criada, mas as estatísticas ficam vazias. Correção: adicione a
preload, reinicie uma vez. - Perseguindo apenas o tempo médio - consulta rara de 5s com 10 chamadas vs 50ms com 1M chamadas. Correção: ordene primeiro por
total_exec_time. - Consultas com muitos literais - milhões de impressões digitais sem normalização de aplicativos. Correção: consultas parametrizadas; instruções preparadas de ORM.
- Reiniciar estatísticas durante um incidente - destrói evidências. Correção: capture as principais consultas em um ticket antes de reiniciar.
- Segurança: texto da consulta visível - pode conter literais de PII. Correção: restrinja
pg_read_all_stats; mascare em exportações. - PgBouncer + pooling de transações - as estatísticas são agregadas no servidor corretamente, mas o mapeamento da sessão do aplicativo é opaco. Correção: use tags
application_namepor serviço.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
log_min_duration_statement | Captura de consulta lenta única | Classificação contínua da carga de trabalho |
| APM (Datadog DBM) | Rastreamento de aplicativo para SQL | Sem orçamento de APM |
auto_explain | Planos de log acima do limite | Sobrecarga de alto volume |
pg_stat_monitor | Histogramas por intervalo | Extensão não disponível |
FAQs
Sobrecarga de desempenho?
Baixo percentual de um dígito em OLTP ocupado com o máximo padrão. Aumente pg_stat_statements.max com cautela.
Com que frequência reiniciar?
Após a implantação principal ou linha de base mensal. Mantenha o CSV exportado das 20 principais anteriores.
Posso desabilitar para um banco de dados?
As estatísticas são para todo o cluster; filtre por dbid nas consultas. A extensão é por cluster.
Impacto na replicação?
Os standbys não executam consultas de aplicativos; habilite no gravador principal. As réplicas de leitura têm suas próprias estatísticas para a carga de trabalho de leitura.
Estabilidade do queryid?
Muda se a normalização do texto da consulta mudar ou em uma atualização principal. Re-baseie após a atualização.
Comandos utilitários rastreados?
Depende de track_utility. A visibilidade DDL é útil para auditoria; pode adicionar ruído.
Junção com pg_stat_activity?
Propósitos diferentes. A atividade é ao vivo; declarações são histórico cumulativo.
Exportar para Grafana?
postgres_exporter expõe as principais métricas ou consulta por meio de scrape de visualização personalizada.
HIPAA e texto da consulta?
Trate as exportações como confidenciais. Mascare literais em pipelines SIEM.
vs Habilidade de revisão EXPLAIN?
Use pg_stat_statements para escolher quais consultas merecem tempo de EXPLAIN.
Relacionado
- Noções Básicas de Monitoramento - visão geral da observabilidade
- Noções Básicas de EXPLAIN - leitura de plano
- postgres_exporter & Grafana - exportação de métricas
- Dashboards SLO - orçamentos de latência
- Melhores Práticas de Monitoramento - checklist operacional
Versões de Stack: Esta página foi escrita para PostgreSQL 18.4 (estável 18, manutenção 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x e PostGIS 3.5+.