Índice é a ferramenta de maior impacto e menor custo para acelerar um banco de dados. Uma consulta que varre dez milhões de linhas em oito segundos passa a responder em cinco milissegundos com o índice certo. Nenhum ajuste de parâmetro chega perto disso.
E é também a ferramenta mais mal usada que existe. A reação padrão a uma consulta lenta é criar um índice; a reação a dez consultas lentas é criar dez. Dois anos depois, a tabela tem vinte índices, metade nunca é usada, a escrita está lenta, o backup dobrou de tamanho e ninguém sabe qual índice pode ser removido com segurança.
O que um índice custa
A troca é sempre a mesma e precisa estar clara antes de qualquer criação:
| Ganha | Paga |
|---|---|
| Leitura muito mais rápida nas consultas que o usam | Toda inserção, atualização e exclusão precisa atualizar o índice |
| Menos leitura de disco | Espaço em disco, às vezes comparável ao da tabela |
| Ordenação e agrupamento mais baratos | Backup maior e restauração mais lenta |
| Verificação de unicidade eficiente | Mais trabalho para a manutenção automática do banco |
Em tabela de alta rotatividade — fila, log, sessão, evento —, o custo de escrita é real e mensurável. Cada índice extra torna a inserção um pouco mais cara, e "um pouco" vezes um milhão de inserções por hora deixa de ser pouco.
A regra: índice existe para atender uma consulta conhecida. Se você não consegue nomear qual consulta ele serve, ele não deveria existir.
Comece pelo plano de execução, não pelo palpite
O banco de dados te diz exatamente o que está fazendo. Todos os bancos relacionais têm um comando que mostra o plano de execução — e, mais importante, uma variação que executa de verdade e mostra tempos e quantidades medidas, não estimadas.
Use sempre a versão que executa. Estimativa errada é justamente uma das causas mais comuns de plano ruim, e comparar o estimado com o real é o que revela o problema.
O que procurar no plano:
- Varredura sequencial em tabela grande quando o filtro deveria ser seletivo. É o sinal mais direto de índice faltando.
- Diferença grande entre linhas estimadas e linhas retornadas. Indica estatística desatualizada — e às vezes a correção é atualizar a estatística, não criar índice.
- Ordenação em disco. A consulta está ordenando um volume que não coube na memória de trabalho. Índice na ordem certa pode eliminar a ordenação inteira.
- Filtro aplicado depois da leitura. O banco leu muito mais linha do que precisava e descartou depois. Índice mais seletivo resolve.
- Junção com método caro em tabelas grandes, normalmente por falta de índice na coluna de junção.
Índice composto: a ordem das colunas decide tudo
Esta é a parte que gera mais confusão e mais índice inútil.
Um índice sobre várias colunas só serve a consultas que filtram pelas colunas a partir da primeira, sem pular. Um índice em (cliente, status, data) atende:
- filtro por
cliente - filtro por
clienteestatus - filtro por
cliente,statusedata
E não atende, de forma eficiente:
- filtro só por
status - filtro só por
data - filtro por
statusedatasemcliente
É a analogia da lista telefônica ordenada por sobrenome e depois nome: achar todos os "Silva" é trivial; achar todos os "João" de qualquer sobrenome exige ler tudo.
A ordem que funciona na maioria dos casos: primeiro as colunas de igualdade, depois as de faixa, depois as de ordenação. Consulta que filtra cliente = X e data entre A e B, ordenando por data, quer um índice em (cliente, data) — nessa ordem.
Consequência prática importante: um índice composto bem desenhado costuma substituir vários índices de coluna única. Antes de criar o terceiro índice em uma tabela, verifique se não é o caso de ter um composto no lugar de três simples.
Por que o meu índice não está sendo usado
Pergunta frequente, com um conjunto pequeno de causas:
- Função aplicada na coluna. Filtrar por
ANO(data) = 2026impede o uso do índice emdata. Reescreva como faixa:data >= '2026-01-01' e data < '2027-01-01'. O mesmo vale para conversão de maiúsculas e para concatenação. - Tipo divergente. Comparar coluna de texto com número, ou tipos diferentes de inteiro, força conversão e descarta o índice.
- Baixa seletividade. Se o filtro retorna 40% da tabela, varrer tudo é mais barato do que pular pelo índice e buscar linha a linha. O banco está certo; o índice é que não ajuda ali.
- Estatística desatualizada. O planejador decide com base em estimativas. Estatística velha gera decisão ruim. Em tabela que mudou muito de volume, atualizar a estatística resolve casos que pareciam exigir índice novo.
- Curinga no início do texto. Busca por
%termonão usa índice comum. Isso é caso para índice de texto ou índice específico de busca por trecho. - A coluna não é a primeira do composto. O item anterior, de novo — e é a causa mais comum de todas.
Índices especiais que valem conhecer
Além do índice comum de árvore, existem tipos que resolvem problemas específicos com muito menos custo:
- Índice parcial, que cobre apenas as linhas que atendem uma condição. Para uma tabela de pedidos em que 98% já foram concluídos e as consultas operacionais só olham os pendentes, um índice parcial sobre os pendentes é uma fração do tamanho e muito mais rápido. É provavelmente o recurso mais subaproveitado do PostgreSQL.
- Índice sobre expressão, quando o filtro realmente precisa de uma função. Você indexa o resultado da função.
- Índice de cobertura, que inclui colunas adicionais para que a consulta seja respondida sem tocar na tabela.
- Índice de texto, para busca por palavras em campo textual.
- Índice invertido, para dados compostos como JSON, vetores e conjuntos.
- Índice único, que além de acelerar garante a regra de negócio de não repetição — e é sempre melhor que validar unicidade na aplicação, porque a aplicação perde a corrida em concorrência.
Encontrar os índices inúteis
Todo banco de produção com alguns anos tem índices que ninguém usa. Eles custam escrita, espaço e tempo de backup, e não devolvem nada.
Todos os bancos relacionais mantêm estatística de uso por índice — quantas vezes cada um foi utilizado desde o último reinício da contagem. É a informação que resolve a limpeza.
O procedimento seguro:
- Listar os índices com contagem de uso zero ou desprezível, depois de um período representativo — no mínimo um mês, para pegar rotinas de fechamento e relatórios mensais.
- Excluir da lista os índices de chave primária e os de restrição de unicidade; eles têm função estrutural.
- Verificar índices duplicados ou redundantes: um índice em
(a)é redundante se já existe(a, b). - Desativar antes de remover, quando o banco permite, e observar.
- Remover fora do horário de pico, um por vez, com o comando de criação guardado para reverter rapidamente.
A limpeza costuma devolver espaço e acelerar escrita de forma perceptível em bancos antigos.
Criar índice sem parar a produção
Criar índice em tabela grande pode bloquear escrita por um tempo longo. Os bancos modernos oferecem criação concorrente, que não bloqueia — é mais lenta e pode falhar no meio, deixando um índice inválido que precisa ser removido e refeito.
Em produção, use sempre a criação concorrente, verifique o resultado ao final e faça isso em janela de menor movimento mesmo assim.
O processo que evita a bagunça
- Identificar as consultas mais custosas pelo acumulado, não pela reclamação isolada.
- Ler o plano de execução real das duas ou três piores.
- Criar o índice em homologação, com volume de dado semelhante.
- Comparar o plano antes e depois, e medir.
- Verificar o impacto na escrita, não só na leitura.
- Registrar em código versionado qual consulta aquele índice atende.
- Revisar o uso dos índices a cada trimestre e remover os órfãos.
O passo 6 é o que mais economiza tempo no futuro: com a consulta anotada, a decisão de remover deixa de ser arriscada.
Erros comuns
- Criar índice sem olhar o plano de execução.
- Um índice por coluna em vez de um composto na ordem certa.
- Errar a ordem das colunas no índice composto.
- Aplicar função na coluna do filtro e anular o índice.
- Indexar coluna de baixa seletividade.
- Ignorar o custo de escrita em tabela de alta rotatividade.
- Nunca revisar nem remover índice não utilizado.
- Manter índices redundantes cobertos por um composto maior.
- Criar índice em produção sem a opção concorrente.
- Validar unicidade só na aplicação, sem índice único no banco.
- Testar em base pequena e concluir que o índice não ajuda.
- Esquecer de atualizar estatística e culpar o índice.
Onde a Solvefy/Cloud entra
Revisão de índices é um dos trabalhos de retorno mais rápido da nossa consultoria de bancos: identificamos as consultas que consomem a maior parte do tempo, lemos os planos, propomos os índices que faltam, apontamos os que sobram e medimos o antes e depois em tempo de resposta, uso de disco e impacto na escrita. Deixamos as decisões documentadas e a rotina de revisão trimestral montada. Trabalhamos com PostgreSQL, MariaDB e MongoDB.
Seu banco está lento e ninguém sabe por quê? Diagnóstico gratuito, sem compromisso, em solvefy.cloud.
Solvefy/Cloud — Infraestrutura que cresce com você.