0Pricing
SQL Interview Prep · Aula

Quando os índices prejudicam: gravações e seletividade

A amplificação de gravações e por que um índice em uma coluna de baixa seletividade é inútil.

Quando os índices prejudicam: gravações e seletividade é uma aula grátis de SQL Interview Prep no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de SQL Interview Prep, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Interview Prep inclui 4 aulas no total.

A pergunta por trás da pergunta

Depois de três lições sobre por que os índices ajudam, os entrevistadores invertem a questão: “Por que não indexar simplesmente todas as colunas?” Um bom candidato explica que os índices têm custos reais, nas escritas e no cache e armazenamento, e que alguns índices jamais serão usados pelo planejador.

Esta lição aborda os dois principais motivos pelos quais um índice pode prejudicar o desempenho: amplificação de escrita e baixa seletividade.

Todo índice torna as escritas mais lentas

Um índice precisa permanecer sincronizado com a tabela. Cada INSERT, cada DELETE e cada UPDATE em uma coluna indexada também precisa atualizar a estrutura do índice. Isso é amplificação de escrita: uma alteração de linha se transforma em uma gravação na tabela mais uma gravação para cada índice afetado.

Uma tabela com oito índices realiza aproximadamente nove vezes mais trabalho de escrita que uma tabela sem índices. Em tabelas com muitas escritas ou alto volume de processamento, esse é um custo significativo.

Exemplo prático: o custo da escrita

Imagine uma tabela de eventos recebendo milhares de linhas por segundo. Cada índice extra faz com que cada inserção exija mais trabalho, dividindo páginas do índice, atualizando folhas e disputando espaço no cache.

Para uma tabela somente de acréscimo e dominada por escritas, a resposta correta costuma ser ter poucos índices ou nenhum além da chave primária e realizar as leituras pesadas em uma réplica ou em um armazém de dados.

-- Each of these indexes adds cost to EVERY insert below
CREATE INDEX ix_events_user ON events (user_id);
CREATE INDEX ix_events_type ON events (event_type);
CREATE INDEX ix_events_ts   ON events (created_at);

INSERT INTO events (user_id, event_type, created_at)
VALUES (42, 'click', now());  -- now updates table + 3 indexes

O que significa seletividade

Seletividade é o quanto uma coluna consegue distinguir as linhas, ou seja, a fração de linhas correspondida por um valor típico. Alta seletividade significa poucas linhas por valor, como em um e-mail ou UUID. Baixa seletividade significa muitas linhas por valor, como em um booleano ou em um status com três opções.

Os índices são vantajosos em colunas de alta seletividade, nas quais uma busca elimina quase tudo. Em colunas de baixa seletividade, geralmente não são vantajosos.

Por que um índice de baixa seletividade é inútil

Suponha que is_active seja verdadeiro para 90% dos usuários. Uma busca no índice retornaria 90% da tabela e, para tantas linhas, o mecanismo faria uma busca no heap para cada uma delas, o que seria mais lento do que simplesmente percorrer a tabela sequencialmente em uma única passagem.

Por isso, o planejador ignora corretamente o índice e realiza uma varredura sequencial. O índice passa a representar apenas custo adicional de escrita e armazenamento, sem oferecer nenhum benefício de leitura.

-- 90% of rows match: the planner will likely skip this index
CREATE INDEX ix_users_active ON users (is_active);
SELECT * FROM users WHERE is_active = true;

O limite aproximado

Uma regra prática útil para mencionar é: quando um predicado corresponde a mais ou menos 5 a 20% de uma tabela, uma varredura sequencial geralmente supera uma varredura de índice, pois as buscas aleatórias no heap custam mais do que ler as páginas sequencialmente.

O ponto exato de transição depende do tamanho das linhas, do armazenamento em cache e da velocidade do armazenamento; por isso, o planejador usa estatísticas, e não um número fixo, para decidir.

Índices parciais ao resgate

Se você consulta apenas os valores raros de uma coluna com distribuição desigual, um índice parcial (PostgreSQL) indexa somente essas linhas: é pequeno, seletivo e barato de manter.

Se 1% dos pedidos estiverem pending e forem os que você consulta constantemente, indexe somente esses pedidos. O índice permanecerá pequeno e o planejador o usará prontamente.

-- Index only the rare, frequently-queried rows
CREATE INDEX ix_orders_pending
  ON orders (created_at)
  WHERE status = 'pending';

Estatísticas desatualizadas induzem o planejador ao erro

O otimizador decide entre índice e varredura com base nas estatísticas das colunas. Se elas estiverem desatualizadas, depois de uma carga em massa ou de uma grande atualização, ele poderá avaliar incorretamente a seletividade e escolher o plano errado.

Quando um entrevistador diz “o índice existe, mas não é usado”, uma ótima resposta inclui atualizar as estatísticas com ANALYZE antes de culpar o índice.

ANALYZE orders;  -- refresh planner statistics

Outras formas de os índices prejudicarem

Complete a resposta mencionando os custos menos conhecidos:

  • Armazenamento e cache: os índices ocupam espaço em disco e disputam memória, expulsando páginas de dados úteis.
  • Índices redundantes ou sobrepostos: são mantidos, mas nunca escolhidos.
  • Fragmentação: sob muitas atualizações, as árvores B se fragmentam e precisam de REINDEX.
  • Confusão do otimizador: muitos índices semelhantes tornam o planejamento mais lento e menos previsível.

Encontrando índices não utilizados

Para justificar uma limpeza em um ambiente real, mencione que o PostgreSQL acompanha o uso dos índices. Índices com idx_scan = 0 são candidatos à remoção: consomem recursos de escrita e espaço sem nunca atender a uma leitura.

SELECT relname AS table_name, indexrelname AS index_name, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0
ORDER BY relname;

Como dizer isso na entrevista

Um resumo completo e equilibrado:

“Os índices têm o custo da amplificação de escrita: cada inserção, atualização ou exclusão os mantém, além de pressionarem o armazenamento e o cache. Eles só são vantajosos em predicados de alta seletividade; em uma coluna na qual a maioria das linhas corresponde, o planejador prefere corretamente uma varredura sequencial, então o índice representa apenas custo adicional. Para colunas com distribuição desigual, recorro a um índice parcial, mantenho as estatísticas atualizadas com ANALYZE e removo os índices não utilizados.”

Verificação rápida

Decida qual índice tem menos probabilidade de compensar o custo.

Recapitulação: quando os índices prejudicam

Principais conclusões:

  • Cada índice acrescenta amplificação de escrita, além de custos de armazenamento e cache.
  • Os índices ajudam em colunas de alta seletividade; em colunas de baixa seletividade, o planejador prefere uma varredura sequencial.
  • Quando mais ou menos 5 a 20% das linhas correspondem, uma varredura geralmente vence.
  • Use um índice parcial para colunas com distribuição desigual que você consulta apenas pelos valores raros.
  • Mantenha as estatísticas atualizadas com ANALYZE e remova os índices não utilizados (idx_scan = 0).

Isso conclui o curso sobre estratégia de indexação: crie índices onde eles realmente compensam e comprove isso usando o plano.

Perguntas Frequentes

A aula “Quando os índices prejudicam: gravações e seletividade” é grátis?

Sim — o texto completo de “Quando os índices prejudicam: gravações e seletividade” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de SQL Interview Prep, atualize para CoddyKit PRO. O curso de SQL Interview Prep inclui 4 aulas no total.

O que vou aprender em “Quando os índices prejudicam: gravações e seletividade”?

A amplificação de gravações e por que um índice em uma coluna de baixa seletividade é inútil. Você pratica SQL Interview Prep com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar SQL Interview Prep?

Nenhuma experiência prévia é necessária. SQL Interview Prep no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Quando os índices prejudicam: gravações e seletividade”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de SQL Interview Prep?

Sim. Cada aula de SQL Interview Prep inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Índices B-Tree e como eles ajudam
  2. Ordem das colunas em índices compostos
  3. Índices de cobertura e varreduras somente de índice
  4. Quando os índices prejudicam: gravações e seletividade
← Voltar para SQL Interview Prep