TechPurger

Como otimizar consultas em banco de dados lentas

Publicado em: 24 de Maio de 2026 • Por: Rinaldo Purger

Consultas SQL lentas são um dos problemas de performance mais comuns em aplicações web. Uma query que demora segundos para executar pode travar uma API inteira e frustrar os usuários.

1. Use o EXPLAIN para diagnósticar

Antes de qualquer otimização, entenda o que o banco de dados está fazendo. O comando EXPLAIN revela o plano de execução da query:

EXPLAIN SELECT * FROM pedidos WHERE cliente_id = 42;

Se você ver type: ALL no resultado (full table scan), é sinal de que um índice está faltando.

2. Crie índices nas colunas certas

Índices são a principal ferramenta para acelerar queries. Crie índices nas colunas usadas em cláusulas WHERE, JOIN e ORDER BY:

-- Índice simples
CREATE INDEX idx_pedidos_cliente ON pedidos(cliente_id);

-- Índice composto (para queries com múltiplas colunas)
CREATE INDEX idx_pedidos_status_data ON pedidos(status, created_at);

3. Evite SELECT *

Buscar todas as colunas é um desperdício quando você precisa apenas de algumas. Especifique exatamente o que precisa:

-- Ruim
SELECT * FROM usuarios WHERE ativo = 1;

-- Bom
SELECT id, nome, email FROM usuarios WHERE ativo = 1;

4. Use LIMIT em consultas grandes

Nunca busque milhares de registros de uma vez. Use paginação com LIMIT e OFFSET:

SELECT id, nome FROM produtos ORDER BY created_at DESC LIMIT 20 OFFSET 0;

Conclusão

A combinação de EXPLAIN para diagnóstico + índices bem criados resolve a grande maioria dos problemas de performance em banco de dados. Monitore suas queries regularmente e otimize proativamente.

8. Evite N+1 Queries no ORM

O problema N+1 acontece ao usar ORMs: você busca uma lista de pedidos e o ORM faz uma query separada para cada pedido buscar o cliente. Com 100 pedidos, são 101 queries. A solução é usar eager loading — no Sequelize use include, no Prisma use include também, no Rails use eager_load.

9. Particionamento de tabelas grandes

Para tabelas com dezenas de milhões de registros, o particionamento divide a tabela em partes menores por critério de data ou ID. Queries que filtram por data só escaneiam a partição relevante. No PostgreSQL 10+: CREATE TABLE pedidos PARTITION BY RANGE (created_at).

10. Ative o slow query log

No PostgreSQL, configure log_min_duration_statement = 500 no postgresql.conf para logar todas as queries acima de 500ms. Em MySQL use slow_query_log = ON com long_query_time = 0.5. Analise esses logs semanalmente para identificar e resolver gargalos antes que virem problemas graves em produção.