Otimização de Banco de Dados: Desempenho SQL e Indexação
O desempenho do banco de dados afeta diretamente a velocidade da aplicação. Este guia cobre a otimização de consultas SQL, estratégias de indexação e dicas de desempenho de banco de dados.
Atualizado em:Por que o desempenho do banco de dados importa
Consultas lentas de banco de dados aumentam o tempo de resposta da aplicação. Consultas de mais de 100ms afetam negativamente a experiência do usuário.
O gargalo do banco de dados pode afetar 80% do desempenho da aplicação. O banco de dados geralmente é o maior gargalo em vez de CPU ou memória.
A otimização reduz os custos de hardware. Consultas mais eficientes requerem menos recursos do servidor.
Estratégias de Indexação
Índice B-Tree: O tipo de índice mais comum. Eficaz para consultas de igualdade (=) e intervalo (<, >, BETWEEN). Chaves primárias e estrangeiras são indexadas automaticamente.
Índice composto: Índice contendo múltiplas colunas. Determine a ordem das colunas com base na ordem da consulta. A primeira coluna na cláusula WHERE deve ser a mais seletiva.
Índice covering: Índice contendo todas as colunas usadas na consulta. Não é necessário acesso à tabela, apenas o índice é lido.
Índice parcial: Índice para linhas que atendem a uma condição específica. Como WHERE is_active = true. Reduz o tamanho do índice.
Manutenção de índices: Remova índices não utilizados. Cada índice desacelera as operações INSERT/UPDATE/DELETE. Verifique o uso do índice com EXPLAIN.
Otimização de Consultas
EXPLAIN / EXPLAIN ANALYZE: Analise o plano de execução da consulta. Mire em Index Scan em vez de Seq Scan (escaneamento completo de tabela).
Problema N+1: Obtenha dados relacionados em uma única consulta (JOIN) em vez de fazer consulta separada para cada registro. Use eager loading em ORMs.
Não use SELECT *: Selecione apenas as colunas necessárias. Isso reduz o tráfego de rede e o uso de memória.
Otimização de JOIN: Evite JOINs desnecessários. Faça JOIN de tabelas menores primeiro. Use INNER JOIN em vez de LEFT JOIN (se possível).
Subquery vs JOIN: Subconsultas correlacionadas são lentas. Use JOIN ou CTE (Common Table Expression) quando possível.
Cache e Connection Pooling
Query cache: Armazene em cache os resultados de consultas frequentemente usadas. Faça caching a nível de aplicação com Redis ou Memcached.
Connection pooling: Reutilize as conexões de banco de dados. Abrir uma nova conexão para cada solicitação é caro. Use pgBouncer (PostgreSQL) ou HikariCP (Java).
Read replicas: Roteie as operações de leitura para servidores replica. Mantenha as operações de escrita no servidor primário. Isso distribui a carga de leitura.
Materialized views: Crie materialized view para consultas de agregação complexas. Atualize periodicamente.
Design de Banco de Dados
Normalização: Reduza a repetição de dados (1NF, 2NF, 3NF). No entanto, a sobre-normalização aumenta o número de JOIN e reduz o desempenho.
Desnormalização: A desnormalização melhora o desempenho em sistemas com muita leitura (analytics, reporting). Trade-off: consistência de dados vs desempenho.
Partitioning: Particione tabelas grandes (milhões de linhas). Range partitioning (baseado em data) é o método mais comum.
Tipos de dados: Use os tipos de dados corretos. INT em vez de VARCHAR, VARCHAR (tamanho apropriado) em vez de TEXT. Tipos de dados menores ocupam menos espaço e são processados mais rápido.
Monitoramento e Profiling
Slow query log: Registre consultas lentas. PostgreSQL: log_min_duration_statement = 100. MySQL: slow_query_log = 1.
Performance Schema (MySQL) / pg_stat_statements (PostgreSQL): Colete estatísticas de consultas. Identifique as consultas que levam mais tempo.
Ferramentas APM: Monitore o desempenho do banco de dados com Datadog, New Relic ou Dynatrace. Rastreie os tempos de consulta e as taxas de erro.
Uso de índices: Verifique o uso de índices com pg_stat_user_indexes (PostgreSQL). Remova índices não utilizados.