PostgreSQL lento? Query optimization e tuning correto aceleram em 100x. EXPLAIN ANALYZE mostra gargalos, índices certos eliminam.
Conceitos Principais
EXPLAIN ANALYZE
Mostra execution plan. Seq Scan vs Index Scan. Cost, rows, time. Identifica bottlenecks.
Query Planning
Postgres escolhe melhor estratégia. Statistics influenciam. ANALYZE atualiza stats. Planner nem sempre acerta.
Connection Pooling
PostgreSQL cria process por conexão. Overhead alto. PgBouncer pool connections. 1000 clients → 20 connections.
Config Tuning
shared_buffers, work_mem, effective_cache_size. Defaults para laptop, não servidor.
Passo a Passo
- Profile Query: EXPLAIN ANALYZE SELECT * FROM users WHERE email = '...'. Veja Seq Scan (ruim) ou Index Scan (bom). Cost e time.
- Adicione Índice: CREATE INDEX idx_users_email ON users(email). Re-run EXPLAIN. Index Scan now. Query 100x mais rápida.
- Optimize JOINs: EXPLAIN ANALYZE SELECT * FROM orders JOIN users ON orders.user_id = users.id. Index em user_id. Nested Loop vs Hash Join.
- Tune Config: postgresql.conf: shared_buffers = 25% RAM, effective_cache_size = 50-75% RAM, work_mem = RAM/(max_connections * 2).
- Setup PgBouncer: Install pgbouncer. pgbouncer.ini: pool_mode = transaction, max_client_conn = 1000, default_pool_size = 20. App conecta pgbouncer:6432.
Boas Praticas
Recomendacoes
• EXPLAIN ANALYZE antes de otimizar
• Índices em WHERE, JOIN, ORDER BY columns
• Partial indexes para queries específicas
• PgBouncer em transaction mode
• Vacuum e Analyze regularmente
• Monitor slow queries (pg_stat_statements)
Erros Comuns
Evite estes erros
• Índices demais (slow writes)
• Não atualizar statistics (ANALYZE)
• work_mem muito alto (OOM)
• Conexões diretas ao Postgres (sem pooling)
• Default config em produção
Checklist
- EXPLAIN ANALYZE em queries lentas
- Índices criados
- postgresql.conf tunado
- PgBouncer instalado
- pg_stat_statements ativo
- Queries < 100ms