trilha

System Design/03 - Qualidade/Performance Antipatterns2 min

Busy Database

Perguntas-guia
  • Que problema isso resolve?
  • Quando usar / quando NÃO usar?
  • Qual o principal trade-off?
  • Como isso falha em produção?

Conceito

Empurrar trabalho para o banco que poderia ser feito em outro lugar — transformando o recurso mais caro e mais difícil de escalar do sistema em gargalo.

O banco é especial por três motivos: normalmente há um primário para escrita, escalá-lo custa muito mais que escalar aplicação, e ele é compartilhado por todos os componentes. Cada ciclo de CPU gasto ali é o ciclo mais caro do sistema.

Formas comuns

Forma Por que é ruim
Lógica de negócio em procedure Difícil de testar, versionar e escalar
Trigger encadeada Efeito invisível; uma escrita dispara cascata
Formatação e apresentação em SQL CPU do banco fazendo trabalho de aplicação
Relatório pesado no primário Compete com o tráfego transacional
Processamento de arquivo/XML/JSON no banco O banco vira servidor de aplicação
Cron implementado como job do banco Sem observabilidade nem controle

Trade-offs

O antipadrão oposto existe e é igualmente real: fazer na aplicação o que o banco faz melhor. Agregação, filtro, ordenação e junção pertencem ao banco — trazê-los para a aplicação é Extraneous Fetching.

A linha divisória prática:

Pertence ao banco Pertence à aplicação
Filtrar, agregar, ordenar, juntar Regra de negócio
Garantir integridade e unicidade Formatação e apresentação
Transação Orquestração entre serviços

Há também um caso legítimo para procedures: operações que exigem várias idas e voltas dentro de uma transação, onde executar no banco elimina latência de rede sob lock. O custo é o de sempre — código fora do repositório principal, testado de forma diferente.

E a saída mais eficaz raramente é reescrever a lógica: é tirar a carga analítica do primário. Réplica de leitura para relatórios (Replication) resolve o sintoma mais comum sem mexer em nada.

Exemplo prático

Uma trigger que, a cada INSERT em pedidos, atualiza estoque, grava auditoria e recalcula o total do cliente.

Do lado da aplicação, é uma escrita simples. Do lado do banco, cada pedido custa quatro operações, segura locks por mais tempo e serializa sob concorrência. Na Black Friday, a contenção derruba o throughput de escrita — e nenhum log da aplicação explica por quê, porque a cascata é invisível a partir dela.

A alternativa é emitir um evento e deixar estoque, auditoria e agregados serem processados fora do caminho crítico (Event-Driven). A escrita volta a custar uma operação; a consistência entre os agregados passa a ser eventual — um trade-off explícito, em vez de um custo escondido.

Relacionado


Parte de Performance Antipatterns · roadmap.sh/system-design

Buscar

Busca por título, seção e texto das notas