Padrões de Revisão de Consultas
Novas consultas SQL em PRs de aplicação precisam do mesmo rigor da revisão de contratos de API. Exija evidências: EXPLAIN, estimativas de linhas e justificativa de índice antes de mesclar para caminhos de produção.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT o.id, o.total
FROM orders o
WHERE o.customer_id = $1
AND o.created_at >= now() - interval '90 days'
ORDER BY o.created_at DESC
LIMIT 50;## Checklist de Revisão SQL de PR
- [ ] EXPLAIN anexado do staging com estatísticas semelhantes às de produção
- [ ] Estimativa de linhas dentro de 10x do real (ANALYZE atual)
- [ ] Justificativa de índice ou prova de que a varredura sequencial é aceitável
- [ ] Nenhum SELECT * em caminhos de alta frequência
- [ ] Tipos de parâmetros correspondem aos tipos de coluna (sem cast implícito)Quando usar isso: Qualquer PR que toque em SQL de repositório, consultas raw de ORM, definições de relatórios ou funções geradas por migração.
Exemplo de Trabalho
Desenvolvedor adiciona consulta de dashboard filtrando orders por status e created_at.
-- Antes de mesclar: revisor executa no staging
EXPLAIN (ANALYZE, BUFFERS)
SELECT count(*) FROM orders
WHERE status = 'pending'
AND created_at > '2026-01-01';
-- O plano mostra Seq Scan em 12M de linhas, 4.2s
-- Revisor solicita evidência de índice
CREATE INDEX CONCURRENTLY orders_status_created_idx
ON orders (status, created_at DESC);
EXPLAIN (ANALYZE, BUFFERS)
SELECT count(*) FROM orders
WHERE status = 'pending'
AND created_at > '2026-01-01';
-- Index Scan, 45msO que isso demonstra:
- Anexe planos antes e depois ao adicionar índices.
ANALYZEno staging após grandes cargas de dados antes de confiar nas estimativas.- Ordem das colunas do índice multicoluna corresponde ao padrão de filtro + ordenação.
- Migração para o índice é enviada em uma etapa de deploy separada quando o nível de risco exige.
Mergulho Profundo
Artefatos Necessários no PR
| Artefato | Propósito |
|---|---|
EXPLAIN (ANALYZE, BUFFERS) | Provar o caminho de acesso e I/O |
Estimativa de rows vs. real | Capturar estatísticas desatualizadas |
| Estimativa de frequência de chamada | Custo = tempo x QPS |
| Sensibilidade a bloqueios | FOR UPDATE em loops de API |
Sanidade da Estimativa de Linhas
SELECT relname, last_analyze, last_autoanalyze, n_live_tup
FROM pg_stat_user_tables
WHERE relname = 'orders';Se as estimativas estiverem fora em 100x, execute ANALYZE orders (ou corrija estatísticas estendidas) antes de aprovar o gasto com índice.
Quando Seq Scan é OK
- Pequenas tabelas de dimensão (< 10k linhas) consultadas uma vez por requisição.
- Relatório de administração único com timeout de instrução e agendamento fora do pico.
- Consulta retorna uma grande fração da tabela onde o índice + busca no heap custa mais.
Documente "seq scan aceito" com prova de contagem de linhas no comentário do PR.
ORM e N+1
-- Detectar padrão: 1 + N consultas no trace APM
-- Corrigir: JOIN ou WHERE id = ANY($1::bigint[])
SELECT * FROM line_items WHERE order_id = ANY($1::bigint[]);Armadilhas
- EXPLAIN sem ANALYZE - Mostra apenas estimativas; esconde o tempo de execução. Correção: Exigir ANALYZE no staging para caminhos de alta frequência.
- Revisão contra tabelas vazias - Scans de índice instantâneos em 0 linhas. Correção: Popular o staging para 10-30% das contagens de linhas de produção.
- Cast implícito anula o índice -
WHERE created_at > $1com parâmetro de texto. Correção: Corresponder tipos; fazer o cast no parâmetro, não na coluna. - LIMIT ausente na ordenação - Ordena milhões de linhas para a página 1 da UI. Correção: Paginação por chave ou filtros mais restritos.
- Novo índice por PR - A proliferação de índices retarda as escritas. Correção: Consolidar índices multicoluna; revisar Tratamento de Solicitações de Índice.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Visão materializada | Agregado caro reutilizado | Frescura < 1 minuto necessária |
| Coluna desnormalizada | Forma estável com muitas leituras | Núcleo normalizado com muitas escritas |
| Apenas pg_stat_statements | Auditoria pós-deploy | Portão pré-merge |
| Reescrever consulta | Ordem de join ruim | Apenas estatísticas ausentes |
FAQs
Quem realiza a revisão de consultas?
DBA ou revisor SQL designado; o líder técnico define o padrão, não gargalha toda PR.
É permitido EXPLAIN da produção?
Réplicas somente leitura sim para SELECT; nunca DDL experimental em produção para revisão.
Qual QPS exige revisão obrigatória?
Política da equipe; limite comum é qualquer consulta esperada > 10 QPS ou que toque > 1M de linhas.
Como revisar SQL oculto por GraphQL/ORM?
Habilitar log SQL em testes de integração de staging; capturar planos em artefato CI.
Escritas precisam de EXPLAIN?
EXPLAIN funciona para INSERT/UPDATE com cuidado; focar em bloqueios e custo de triggers.
E declarações preparadas?
Planos podem diferir; testar com o mesmo caminho de prepare/execute que o PgBouncer usa.
Revisores devem executar VACUUM?
Não na revisão; garantir que o autovacuum esteja saudável para que as estatísticas do ANALYZE sejam confiáveis.
Como armazenar EXPLAIN em PR?
Colar o plano de texto ou linkar o artefato CI; armazenar no ticket de migração para índices.
CTEs são sempre barreiras de otimização?
PostgreSQL 12+ insere muitas CTEs; ainda verificar o plano após a reescrita.
O que devo ler em seguida?
Veja Tratamento de Solicitações de Índice para o fluxo de aprovação.
Relacionados
- Tratamento de Solicitações de Índice - aprovação de índice
- Noções Básicas de EXPLAIN - leitura de planos
- Revisão de Código para SQL - fluxo de trabalho git
- pg_stat_statements - auditoria de produção
Versões da 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+.