Índices
A estrutura que faz uma consulta cair de segundos para milissegundos, e o que ela custa na escrita.
O problema: procurar sem índice
Imagine uma tabela com dois milhões de pedidos e a consulta mais comum do sistema: os pedidos de um cliente.
SELECT * FROM pedidos WHERE cliente_id = 4242;Sem nenhuma ajuda, o banco só tem uma forma de responder: ler as dois milhões de linhas, uma por uma, e separar as 22 que pertencem ao cliente. Isso se chama varredura sequencial (sequential scan). Num teste com essa tabela no PostgreSQL, ela levou 77 milissegundos.
Parece pouco, mas o tempo cresce junto com a tabela, e a consulta roda a cada vez que alguém abre a tela de pedidos. Com dez vezes mais dados ou cem usuários ao mesmo tempo, o banco passa o dia lendo linhas que não interessam a ninguém.
A ideia do índice
Um índice resolve o problema do mesmo jeito que o índice remissivo de um livro. Em vez de folhear todas as páginas atrás de um assunto, você vai ao final do livro, encontra o termo em ordem alfabética e lê os números das páginas.
O índice de banco é uma cópia de uma ou mais colunas, mantida em ordem, em que cada valor aponta para a linha correspondente na tabela.
CREATE INDEX idx_pedidos_cliente ON pedidos (cliente_id);Com o índice criado, a mesma consulta levou 0,12 milissegundo, mais de 600 vezes mais rápida. O banco foi direto aos 22 registros.
Como o índice encontra o valor
O tipo mais comum de índice é a árvore B (B-tree). Ela organiza os valores em níveis, como um índice de livro com subdivisões:
[ 30000 | 60000 ]
/ | \
[ 10000 | 20000 ] [ 40000 | 50000 ] [ 70000 | 80000 | 90000 ]
/ | \ ... ...
folhas com os valores em ordem, cada um apontando para a linhaCada nível descarta a maior parte dos valores. Com dois milhões de linhas, a árvore tem só três ou quatro níveis. Chegar a qualquer valor custa três ou quatro leituras, em vez de dois milhões. Quando a tabela dobra de tamanho, a árvore ganha no máximo um nível.
Como as folhas estão em ordem, a árvore B também atende:
- buscas por intervalo:
WHERE criado_em > '2026-01-01'; - ordenação:
ORDER BY criado_em DESC, sem precisar ordenar depois; - prefixos de texto:
WHERE email LIKE 'marina%', com a configuração de ordenação adequada.
O que o índice custa
O índice não é de graça. Toda gravação na tabela também precisa atualizar cada índice dela.
| Custo | O que acontece |
|---|---|
| Escrita mais lenta | Cada INSERT, UPDATE de coluna indexada e DELETE mexe na tabela e em todos os índices |
| Espaço em disco | No teste, a tabela tinha 174 MB; um índice de uma coluna ocupou 15 MB e um índice sobre um texto, 95 MB |
| Memória | Índices consultados com frequência precisam caber em memória para serem rápidos |
No mesmo teste, inserir 500 mil linhas levou 1 segundo numa tabela só com a chave primária e 5,4 segundos numa tabela com a chave primária e mais cinco índices.
Por isso a regra não é "indexe tudo". É indexar o que as consultas frequentes usam, e nada além disso.
Seletividade: quando o índice ajuda
Um índice só vale a pena quando a consulta separa poucas linhas do total. Essa proporção se chama seletividade.
| Consulta | Linhas encontradas | Índice ajuda? |
|---|---|---|
WHERE cliente_id = 4242 | 22 de 2 milhões | Muito |
WHERE email = '...' | 1 de 2 milhões | Muito |
WHERE status = 'pago' | 400 mil de 2 milhões (20%) | Pouco ou nada |
No caso do status, o banco precisaria saltar para 400 mil posições espalhadas pela tabela. Ler tudo em sequência acaba custando quase o mesmo, e às vezes menos. O planejador do banco faz essa conta sozinho e pode decidir ignorar um índice que existe.
Índices com mais de uma coluna
Um índice pode ter várias colunas. A ordem delas importa, porque os valores ficam ordenados pela primeira coluna, depois pela segunda dentro da primeira, e assim por diante, como uma lista telefônica ordenada por sobrenome e depois por nome.
CREATE INDEX idx_pedidos_cliente_data ON pedidos (cliente_id, criado_em DESC);Esse índice atende a tela "últimos pedidos do cliente" por inteiro: encontra o cliente e já percorre os pedidos dele em ordem de data, parando nos 20 primeiros. Mas ele não serve para buscar pedidos só pela data, sem o cliente, assim como a lista telefônica não ajuda a achar todo mundo chamado Marina. No teste, a consulta só por data continuou lendo a tabela inteira mesmo com esse índice.
Por que isso importa quando a IA escreve o código
Um assistente escreve a consulta certa e quase nunca cria o índice que ela precisa, porque o índice mora na migração, longe do código que faz a busca. Os problemas aparecem com volume:
- A consulta funciona em desenvolvimento, com cem linhas, e trava em produção, com milhões.
- A busca usa
lower(email)ouLIKE '%texto%', e o índice existente deixa de ser usado. - O índice composto é criado com as colunas na ordem errada para a consulta.
- Cada sugestão de otimização acrescenta mais um índice, e as gravações ficam lentas.
O próximo nível compara os tipos de índice e mostra como decidir o que indexar.
Prompts para aprofundar
Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.
Índices em cinco minutos
Explique em no máximo cinco minutos de leitura o que é um índice de banco de dados, para alguém que programa mas nunca otimizou uma consulta. Cubra só o essencial: o que acontece numa consulta sem índice, como o índice encontra os dados, o que ele custa na escrita e por que nem toda coluna deve ter índice. Use a analogia do índice remissivo de um livro. No final, me faça três perguntas curtas para eu verificar se entendi, e corrija as minhas respostas.
Por dentro de uma árvore B
Quero entender como um índice de árvore B funciona por dentro. Aja como um mentor de bancos de dados. Pergunte primeiro qual é a minha experiência com SQL. Conduza assim, uma etapa por vez, com uma pergunta de verificação ao fim de cada uma: 1. O que o banco faz para responder uma consulta numa tabela sem índice, e por que o tempo cresce com a tabela. 2. A estrutura de uma árvore B: nós, níveis e folhas, com um desenho em texto. Mostre quantos níveis uma tabela de dez milhões de linhas teria. 3. O caminho de uma busca por igualdade, de uma busca por intervalo e de uma consulta com ORDER BY e LIMIT. 4. O que acontece com o índice a cada INSERT, UPDATE e DELETE. No final, peça que eu explique com minhas palavras por que um índice acelera a leitura e encarece a escrita, e corrija o que estiver impreciso.
Seletividade e as decisões do planejador
Quero entender por que o banco às vezes ignora um índice que existe. Explique: 1. O que é seletividade, com exemplos de colunas de alta e de baixa seletividade. 2. Como o planejador estima quantas linhas uma consulta vai retornar, e de onde vêm essas estatísticas. 3. Por que ler a tabela inteira pode ser mais barato do que usar o índice quando a consulta retorna muitas linhas. 4. O que acontece quando as estatísticas estão desatualizadas. Depois me apresente cinco consultas sobre uma tabela de pedidos com dois milhões de linhas, informando quantas linhas cada uma retorna, e pergunte se o banco deve usar o índice em cada caso. Corrija as minhas respostas.
Índices compostos e a ordem das colunas
Quero entender de vez como funcionam os índices com mais de uma coluna. Use a analogia de uma lista telefônica ordenada por sobrenome e depois por nome, e explique por que a ordem das colunas decide quais consultas o índice atende. Depois, crie um índice composto de exemplo numa tabela de pedidos e me apresente oito consultas, uma por vez, perguntando se o índice atende cada uma, total ou parcialmente. Inclua consultas com igualdade, com intervalo, com ORDER BY, com IN, com a segunda coluna sozinha e com OR. Corrija cada resposta e, no final, me dê a regra prática para ordenar as colunas de um índice composto.