PostgreSQL lento: 7 causas comuns e como diagnosticar
Consultas lentas no PostgreSQL? Veja como investigar índices, estatísticas, autovacuum, conexões, locks e configuração com método.
PostgreSQL lento é sintoma, não diagnóstico. A diferença entre resolver e piorar o ambiente está em medir antes de mexer. Antes de criar índices ou aumentar parâmetros, é preciso saber onde o tempo é consumido: consulta, espera, I/O, CPU, locks ou conexão.
Comece pelas evidências
As três fontes mais úteis em qualquer investigação são pg_stat_statements, os planos de execução e os logs de consultas lentas. Com elas, você descobre quais consultas consomem mais tempo total e quais sofrem com estimativas erradas.
-- Consultas que mais consomem tempo total
SELECT queryid, calls, mean_exec_time, total_exec_time, query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;As 7 causas mais comuns
1. Índice ausente ou inadequado
A consulta varre a tabela inteira porque não existe índice para o filtro ou porque o índice existe em uma ordem que não atende ao join. O plano de execução mostra Seq Scan em tabelas grandes com filtro seletivo.
2. Estatísticas desatualizadas
O planejador estima poucas linhas e escolhe um plano ruim. Tabelas que recebem muitas inserções, updates ou deletes precisam de analyze frequente. autovacuum ajuda, mas nem sempre no ritmo necessário.
3. Autovacuum atrasado e bloat
Atualizações e exclusões deixam versões mortas. Sem vacuum, a tabela e os índices incham, o I/O aumenta e as consultas ficam mais lentas. O monitoramento de bloat e de transações antigas é obrigatório.
4. Consultas mal escritas ou N+1
Joins desnecessários, subconsultas repetidas, paginação por offset em tabelas grandes e a aplicação chamando o banco dentro de loops são causas comuns que nenhum índice resolve sozinho.
5. Conexões demais ou pool mal configurado
Muitas conexões simultâneas competem por CPU e memória. Um pool bem dimensionado costuma render mais que aumentar max_connections. O contrário também acontece: pool pequeno cria fila na aplicação.
6. Configuração inadequada
shared_buffers, work_mem, autovacuum, checkpoint e WAL precisam conversar com o hardware e o perfil de carga. Copiar configuração de outro ambiente é uma das formas mais rápidas de piorar a performance.
7. Locks e concorrência
Consultas esperando lock não aparecem como lentas no tempo de execução, mas travam a operação. Verifique pg_stat_activity, pg_locks e bloqueios de longa duração antes de concluir que o problema é CPU.
SELECT pid, now() - query_start AS duracao, wait_event_type, wait_event, state, query
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY duracao DESC;O que evitar
- Criar índice para toda consulta sem medir o impacto na escrita
- Desligar autovacuum para ganhar tempo
- Aumentar work_mem globalmente sem calcular o consumo máximo
- Reiniciar o banco como primeira ação
- Alterar parâmetros em produção sem registrar o antes e o depois
Quando chamar um especialista
Se o problema volta depois de ajustes pontuais, se o horário de pico derruba a aplicação ou se ninguém consegue interpretar os planos de execução, vale um diagnóstico estruturado. A otimização precisa ser medida antes e depois, com evidência do ganho.
Precisa de ajuda com este tema?
A PostDB atua com DBA gerenciado, migração, tuning e alta disponibilidade para PostgreSQL. O diagnóstico inicial de 30 minutos é gratuito.
Perguntas frequentes
Criar mais índices sempre melhora a performance?
Não. Cada índice acelera algumas leituras, mas aumenta o custo de escrita, o uso de disco e a manutenção do vacuum. Índices precisam ser justificados por consultas reais e revisados periodicamente.
Por que a consulta ficou lenta do nada?
As causas mais comuns são mudança de volume, estatísticas desatualizadas, crescimento de tabelas, alteração no plano de execução, locks ou esgotamento de conexões. Comparar o plano atual com o histórico e medir o tempo por etapa ajuda a localizar a causa.
Aumentar work_mem resolve problemas de lentidão?
Pode ajudar consultas específicas que fazem ordenação ou hash em disco, mas o parâmetro é por operação e por conexão. Aumentar globalmente pode consumir toda a memória do servidor. O ajuste deve ser pontual e medido.
Continue lendo
Migração de Oracle para PostgreSQL: como planejar sem perder dados
O que muda entre Oracle e PostgreSQL, as fases de uma migração segura e os erros que mais atrasam projetos de corte.
Alta disponibilidadeAlta disponibilidade no PostgreSQL: replicação, Patroni e failover
Réplica configurada não é alta disponibilidade. Entenda o que precisa ser testado para uma falha de servidor não virar indisponibilidade.