Custo de Escrita e Manutenção de Índices: Impacto em INSERT, UPDATE e DELETE

Capítulo 7

Tempo estimado de leitura: 8 minutos

+ Exercício

Índices aceleram leitura, mas “cobram pedágio” na escrita

Quando você cria um índice, você ganha velocidade em consultas de leitura (SELECT), porque o banco passa a ter uma estrutura extra para localizar linhas com menos trabalho. O custo é que essa estrutura precisa ser mantida sempre que os dados mudam. Em termos práticos: cada INSERT, UPDATE ou DELETE pode exigir alterações em um ou vários índices, além da própria tabela.

Uma forma útil de pensar: para cada índice adicional, você está adicionando mais “lugares” onde o banco precisa escrever. Em cargas com muita escrita, isso pode virar o gargalo.

O que exatamente é “manutenção de índice”

  • Inserção: além de gravar a nova linha na tabela, o banco precisa inserir uma nova entrada em cada índice aplicável.
  • Atualização: se a atualização mexer em colunas indexadas (ou em colunas que participam do índice), o banco pode precisar remover a entrada antiga e inserir uma nova (na prática, é como um “delete + insert” dentro do índice).
  • Deleção: o banco precisa remover (ou marcar como removida) a entrada do índice e, em muitos mecanismos, lidar depois com limpeza/compactação.

Além disso, índices ocupam espaço e podem sofrer fragmentação (páginas com buracos, páginas meio vazias, mais saltos de leitura), o que pode exigir reorganização ou rebuild dependendo do banco.

Impacto em INSERT: páginas e “splits” (conceito)

Muitos índices (especialmente B-tree) armazenam dados em páginas (blocos). Quando você insere uma nova chave, o banco precisa colocá-la na página correta para manter a ordem. Se a página já estiver cheia, ocorre um page split (divisão de página): o banco cria uma nova página, move parte das entradas e ajusta ponteiros. Isso aumenta o custo do INSERT porque vira mais I/O e mais trabalho interno.

Quando INSERT tende a ser mais caro

  • Muitos índices na tabela: cada INSERT atualiza todos eles.
  • Chave do índice “espalha” inserções: se a chave inserida cai em posições aleatórias do índice, aumenta a chance de splits e fragmentação.
  • Alta concorrência: mais escrita simultânea pode aumentar contenção (locks/latches) nas páginas do índice.

Passo a passo prático: como perceber que INSERT está pagando caro por índices

  1. Meça o tempo do INSERT (antes/depois) em um ambiente de teste com volume representativo.
  2. Conte quantos índices existem na tabela e identifique quais são realmente usados por consultas frequentes.
  3. Observe sinais de splits/fragmentação nas ferramentas do seu banco (visões de estatísticas/DMVs/relatórios). O nome exato muda, mas a ideia é procurar métricas de “fragmentation”, “page splits”, “leaf page density” ou equivalentes.
  4. Teste removendo/ajustando índices não essenciais (em staging) e compare throughput de escrita.

Impacto em UPDATE: quando atualizar vira “mover” no índice

Nem todo UPDATE custa igual. Se você atualiza uma coluna que não participa de nenhum índice, o banco normalmente altera só a linha (e talvez algum metadado interno). Mas se você atualiza uma coluna indexada, o índice precisa refletir o novo valor.

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

Dois cenários comuns

  • UPDATE em coluna não indexada: custo principal é localizar a linha e gravar a mudança.
  • UPDATE em coluna indexada: o banco precisa remover a entrada antiga do índice e inserir a nova na posição correta. Isso pode causar splits e fragmentação, parecido com INSERT.

Em índices compostos, atualizar qualquer coluna que faça parte da chave do índice pode exigir essa remoção/inserção. Além disso, se a atualização aumenta o tamanho da linha (por exemplo, um texto maior), alguns bancos podem precisar realocar a linha, o que também afeta estruturas que apontam para ela.

Exemplo prático (conceitual)

-- Imagine um índice em (status, created_at)

Se você faz:

UPDATE pedidos SET status = 'enviado' WHERE id = 123;

O banco pode precisar tirar a entrada antiga do índice (status='pago', created_at=...) e inserir uma nova (status='enviado', created_at=...). Em uma tabela com alto volume de atualizações de status, esse índice pode virar um custo constante.

Passo a passo prático: reduzindo custo de UPDATE relacionado a índices

  1. Liste as colunas mais atualizadas (por exemplo: status, flags, campos de “último acesso”).
  2. Verifique se essas colunas estão indexadas e se o índice é realmente necessário para consultas críticas.
  3. Evite indexar campos muito “mutáveis” quando o ganho de leitura não compensa o custo de escrita.
  4. Se a consulta precisa do índice, avalie alternativas: ajustar o índice para atender a consulta com menos colunas, ou mudar a estratégia de consulta para reduzir dependência desse campo.

Impacto em DELETE: marcação, limpeza e espaço

Em muitos bancos, um DELETE não significa “apagar imediatamente tudo do disco”. Frequentemente ocorre:

  • Marcação lógica: a linha é marcada como removida.
  • Remoção/atualização de entradas nos índices: a estrutura do índice precisa deixar de apontar para aquela linha.
  • Limpeza posterior: processos internos (ou manutenção) podem consolidar espaço, remover versões antigas e reduzir fragmentação.

O efeito prático: DELETE pode ser caro em tabelas com muitos índices, e também pode deixar “buracos” (espaço não reaproveitado imediatamente), aumentando fragmentação e impactando leituras futuras.

Passo a passo prático: lidando com deleções frequentes

  1. Meça a taxa de DELETE e identifique tabelas com deleção intensa.
  2. Verifique quantos índices existem nessas tabelas (cada um precisa ser atualizado).
  3. Monitore fragmentação e crescimento: deleções podem manter o arquivo grande mesmo com menos linhas ativas.
  4. Planeje manutenção (reorganização/rebuild/compactação) conforme as ferramentas do seu banco e janelas de operação.

Quantos índices são “demais”?

Não existe um número mágico, porque depende do padrão de acesso. Mas existe um princípio prático: cada índice deve pagar o próprio custo. Se um índice não é usado (ou é raramente usado), ele só adiciona:

  • Mais tempo de escrita (INSERT/UPDATE/DELETE mais lentos).
  • Mais armazenamento (o índice é uma cópia parcial/ordenada de dados + ponteiros).
  • Mais manutenção (estatísticas, reorganização, rebuild, cache/buffer).

Sinais de excesso de índices

  • Escritas lentas mesmo com consultas simples de INSERT/UPDATE.
  • Muitos índices parecidos (mesmas colunas em ordens diferentes, ou índices redundantes).
  • Índices “de tentativa” criados para casos pontuais e nunca revisados.
  • Crescimento de armazenamento desproporcional ao crescimento de dados.

Checklist prático para “enxugar” índices com segurança

  1. Inventarie os índices por tabela (nome, colunas, tipo, tamanho).
  2. Verifique uso real (estatísticas de uso do banco, logs de consultas, APM). Procure índices com baixa ou nenhuma leitura.
  3. Identifique redundância: um índice pode cobrir outro (por exemplo, um índice mais “largo” pode tornar um mais “estreito” desnecessário, dependendo do banco e das consultas).
  4. Teste a remoção em staging e rode o conjunto de consultas críticas + carga de escrita. Compare latência e throughput.
  5. Remova por etapas (um índice por vez) para isolar impacto.

Balanceando leitura vs escrita por perfil de carga (conceitual)

Cargas tipo OLTP (muitas transações curtas, muita escrita)

  • Priorize poucos índices, bem escolhidos, focados nas consultas mais críticas (as que realmente precisam ser rápidas).
  • Evite indexar campos muito atualizados (status, flags voláteis) se não forem essenciais.
  • Revise índices regularmente: em OLTP, um índice “a mais” pode derrubar throughput.
  • Planeje manutenção para reduzir fragmentação quando necessário, mas com cuidado para não competir com a carga.

Cargas analíticas (mais leitura pesada, menos escrita)

  • Aceite mais índices se eles reduzirem muito o custo das consultas (filtros, ordenações, junções), porque a escrita é menos frequente.
  • Escritas em lote (quando existem) podem sofrer com muitos índices; considere janelas de carga e manutenção.
  • Armazenamento e manutenção ainda importam: índices demais podem aumentar custo operacional e tempo de carga.

Regra prática de decisão

Se o seu sistema...TendênciaEstratégia
Escreve o tempo todo (muitos INSERT/UPDATE/DELETE)Menos índicesManter só os que sustentam consultas essenciais e integridade/constraints necessárias
Lê muito mais do que escreveMais índicesAdicionar índices que reduzam custo de consultas recorrentes, monitorando espaço e manutenção
Tem picos de escrita e picos de leituraEquilíbrioÍndices para o “caminho crítico” + revisão periódica + manutenção planejada

Agora responda o exercício sobre o conteúdo:

Por que adicionar muitos índices pode piorar o desempenho de INSERT, UPDATE e DELETE em uma tabela?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

Índices aceleram leituras, mas precisam ser mantidos. Em INSERT/UPDATE/DELETE, o banco pode ter que inserir/remover entradas em cada índice, e ainda lidar com page splits e fragmentação, aumentando custo e contenção.

Próximo capitúlo

Cobertura de Consultas e Índices que Evitam Leitura da Tabela (Conceito de Covering)

Arrow Right Icon
Capa do Ebook gratuito Índices e Performance de Banco de Dados para Iniciantes: Como Acelerar Consultas sem Mistério
50%

Índices e Performance de Banco de Dados para Iniciantes: Como Acelerar Consultas sem Mistério

Novo curso

14 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.