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:
- Consultas mais custosas por tempo total acumulado, não apenas pela duração média de uma execução.
- Planos de execução das consultas críticas, com
EXPLAINno MySQL eEXPLAIN ANALYZEno PostgreSQL. - Data da última atualização de estatísticas e se elas refletem a distribuição real dos dados.
- Quantidade e tempo de vida das conexões abertas: pool mal dimensionado derruba performance sem nenhuma query ruim.
- Locks, transações longas e bloqueios que fazem fila na aplicação.
- 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.