Quando você tá trampando em projetos reais, milhares de usuários podem estar mexendo no seu app ao mesmo tempo. Eles mandam queries pro banco, adicionam dados, leem, atualizam... E aí você percebe que seu servidor começa a "chorar". Isso é um sinal de que suas queries tão longe de serem otimizadas. Às vezes aquela query que parecia de boa "no papel" pode virar um desastre pra sua performance. É aí que entra o pg_stat_statements na jogada.
pg_stat_statements te permite:
- Monitorar queries lentas.
- Sacar quantas vezes cada query foi executada.
- Ver quanto tempo elas gastaram.
- Ver o tempo médio de execução da query.
- Evitar o erro fatal de reescrever o app inteiro!
Explorando a estrutura do pg_stat_statements
Depois de ativar a extensão, aparece uma view especial no seu banco chamada pg_stat_statements. Lá ficam todos os dados das queries executadas. Bora ver o que tem nela:
SELECT * FROM pg_stat_statements LIMIT 1;
O resultado pode ser assim (versão simplificada):
| query | calls | total_time | rows | shared_blks_read |
|---|---|---|---|---|
| SELECT * FROM students | 500 | 20000 ms | 5000 | 100 |
Explicação rápida:
query— a própria query SQL.calls— quantas vezes essa query rodou.total_time— quanto tempo, no total, a query gastou.rows— quantas linhas a query retornou.shared_blks_read— quantos blocos foram lidos (vai pro disco se não tiver no cache).
Analisando os resultados
Agora que o pg_stat_statements tá ligado, bora ver como achar as queries lentas.
As queries mais lentas
Pra descobrir quais queries tão gastando mais tempo, usa essa query aqui:
SELECT query, total_time, calls, mean_time
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 5;
Aqui:
mean_time— é o tempo médio de execução de cada query (total_time / calls).ORDER BY total_time DESC— ordena pelo tempo total gasto.
Queries que rodam toda hora
Às vezes o problema não é a query ser lenta, mas sim rodar vezes demais. Tipo assim:
SELECT query, calls
FROM pg_stat_statements
ORDER BY calls DESC
LIMIT 5;
Otimizando queries
- Use indexação
Se você vê que queries em certas colunas tão lentas, confere se tem índice nessas colunas. Por exemplo, se você tem uma tabela students com um monte de linhas, e sempre consulta o campo last_name, vale criar um índice:
CREATE INDEX idx_students_last_name ON students (last_name);
- Reescreva a query
Imagina que você vê uma query tipo SELECT * FROM orders WHERE amount > 1000 demorando demais. Provavelmente, ao invés de pegar "tudo de tudo", é melhor buscar só as colunas que precisa:
SELECT order_id, amount FROM orders WHERE amount > 1000;
Limpando as estatísticas
Às vezes, pra ver só os resultados novos (tipo depois de otimizar algo), você precisa limpar os dados do pg_stat_statements. Faz assim:
SELECT pg_stat_statements_reset();
Funciona tipo o botão "Resetar" da sua calculadora. Depois disso, as estatísticas começam do zero.
Caçando queries problemáticas
Imagina que você é admin do banco de dados de uma universidade, e a galera tá reclamando que o portal do aluno tá carregando devagar demais. Você decide checar o pg_stat_statements:
Passo 1: Achar as queries mais lentas
SELECT query, total_time, calls, mean_time
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 1;
Você vê que uma query tipo SELECT * FROM students WHERE status = 'active' tá levando 30 segundos. Caraca. Precisa resolver isso já.
Passo 2: Checar indexação Analisando a tabela students, você percebe que a coluna status não tem índice. Bora corrigir:
CREATE INDEX idx_students_status ON students (status);
Passo 3: Conferir o resultado Depois de otimizar, você olha de novo o pg_stat_statements e vê que a query agora roda em 0.5 segundo. Sucesso!
Erros comuns usando pg_stat_statements
Às vezes os admins dão umas vaciladas na hora de analisar as queries:
- Extensão não ativada. Se você esqueceu de colocar o
pg_stat_statementsnoshared_preload_libraries, não vai rolar estatística nenhuma. - Ignorar indexação. Mesmo se as queries tão lentas, às vezes só falta criar o índice certo.
- Não resetar as estatísticas. Se você não roda o
pg_stat_statements_reset(), os dados antigos atrapalham a análise do que tá rolando agora.
Usar o pg_stat_statements no seu trampo é tipo ter um GPS pro banco de dados: ele mostra exatamente onde você tá preso no "engarrafamento" e ainda dá umas dicas de como desviar. Se configurar direitinho, esse recurso pode turbinar a performance do seu banco de dados.
GO TO FULL VERSION