O gargalo quase nunca está onde a reunião aponta

Quando uma tela do sistema fica lenta, a primeira proposta costuma ser trocar de banco, aumentar a máquina ou reescrever o módulo inteiro. Na maior parte dos casos o problema é mais estreito: uma consulta que não usa o índice certo, um plano de execução que mudou porque as estatísticas envelheceram, ou uma aplicação que abre conexões demais e deixa o banco esperando. Trocar de tecnologia antes de entender o gargalo costuma apenas deslocar o problema e adicionar um projeto de migração no meio do caminho.

Diagnóstico começa com medição. Sem saber qual consulta consome mais tempo total, qual tabela cresceu e qual recurso saturou (CPU, I/O, memória, locks), qualquer mudança é aposta com prazo de validade curto.

O que medir antes de mexer em índice

A ordem importa, porque índice criado sem critério custa caro em escrita, espaço e tempo de manutenção. Antes de criar ou remover qualquer índice, vale levantar:

  1. Consultas mais custosas por tempo total acumulado, não apenas pela duração média de uma execução.
  2. Planos de execução das consultas críticas, com EXPLAIN no MySQL e EXPLAIN ANALYZE no PostgreSQL.
  3. Data da última atualização de estatísticas e se elas refletem a distribuição real dos dados.
  4. Quantidade e tempo de vida das conexões abertas: pool mal dimensionado derruba performance sem nenhuma query ruim.
  5. Locks, transações longas e bloqueios que fazem fila na aplicação.
  6. Ritmo de crescimento das tabelas e o efeito disso nas varreduras completas.

PostgreSQL e MySQL: diferenças que mudam a rotina

No PostgreSQL, a rotina gira em torno de MVCC e bloat, autovacuum, estatísticas atualizadas por ANALYZE e uso consciente de índices parciais e de expressão. Um autovacuum mal ajustado degrada leitura de forma silenciosa.

No MySQL com InnoDB, o buffer pool é a decisão central de memória, e a chave primária define a organização física da tabela: chaves aleatórias (UUID, por exemplo) espalham inserções e aumentam I/O. Estatísticas de índice e o desenho das consultas completam o quadro.

O ponto comum é que os dois bancos exigem leitura de plano de execução com contexto, e ambos sofrem com o mesmo padrão vindo do ORM: consultas disparadas dentro de laços, uma por item de uma lista.

Um exemplo típico em distribuidora: a tela de pedidos começa a demorar conforme a base cresce. O diagnóstico mostra uma consulta que filtra por filial e período sem índice composto adequado, somada a dezenas de consultas por item geradas pelo ORM. O ajuste é índice composto, reescrita da consulta com junção e paginação real. Nenhuma troca de banco, nenhuma máquina nova.

Na prática

Para quem mantém software em produção, performance de banco é rotina, não projeto pontual:

  • Revisar semanalmente o log de consultas lentas e priorizar por tempo total, não por reclamação isolada.
  • Tratar toda migration como mudança de performance: avaliar índice, volume e tempo de bloqueio antes de aplicar.
  • Revisar o pool de conexões junto com o time de aplicação, porque o limite do banco e o do servidor precisam conversar.
  • Registrar o antes e o depois de cada ajuste, com a mesma consulta e a mesma massa de dados, para saber o que funcionou.
  • Definir um orçamento de latência por tela crítica e acompanhar esse número ao longo dos releases.
  • Só considerar troca de banco quando o diagnóstico mostrar que o limite é da tecnologia, e não da consulta, do índice ou do acesso.