DBAtlas · Atlas de operações de banco de dados

Decisão: qual tipo de índice?

O tipo de índice correto depende do padrão de acesso da consulta (igualdade, intervalo ou busca textual/JSON), da cardinalidade da coluna e do equilíbrio entre leitura e gravação. O índice errado desperdiça espaço e ainda deixa as gravações mais lentas. Esta árvore parte do formato da consulta e orienta você entre as opções B-tree, Hash, Bitmap, GIN/GiST, índice parcial e covering index, e lembra que a ordem das colunas é crítica em um índice composto.

Como a sua consulta usa esta coluna?

O padrão de acesso é o fator mais decisivo na escolha de um índice. Você apenas compara a coluna com '=', faz intervalo/ordenação (>, <, BETWEEN, ORDER BY), ou busca texto completo, um campo JSON, dados geométricos/arrays? Comece por aqui; não escolha um tipo de índice até que a necessidade esteja clara.

  • Igualdade e intervalo/ordenação combinados (=, >, <, BETWEEN, ORDER BY)
  • Apenas igualdade (=), sem intervalo nem ordenação
  • Busca full-text, em campo JSON/JSONB, array ou geométrica
  • A consulta sempre visa o mesmo pequeno subconjunto de linhas (ex.: WHERE status='active')

Qual é a cardinalidade da coluna (número de valores distintos)?

Se houver necessidade de intervalo/ordenação, o padrão é B-tree; porém, para colunas com pouquíssimos valores distintos (baixa cardinalidade: gênero, status, sim/não) em um data warehouse com muitas leituras, um índice Bitmap pode ser melhor. A coluna tem muitos valores únicos ou poucos valores que se repetem?

  • Alta cardinalidade (muitos valores únicos) ou carga OLTP
  • Baixa cardinalidade e muitas leituras / data warehouse (DWH)

A consulta lê apenas as colunas do índice?

O padrão de acesso é adequado a um B-tree. Uma última otimização: se todas as colunas que a consulta retorna e filtra estiverem no índice, o engine pode responder apenas pelo índice, sem visitar a tabela (index-only / covering scan). Sua consulta lê poucas colunas ou precisa da maior parte da linha?

  • Sim, poucas colunas; pode ser respondida sem visitar a tabela
  • Não, o acesso padrão basta

Recomendação: B-tree (padrão)

Um B-tree é uma estrutura de árvore balanceada que suporta uma ampla gama de padrões de acesso: igualdade, intervalo, ordenação (ORDER BY), correspondência de prefixo com LIKE 'abc%' e MIN/MAX. É o tipo de índice padrão na maioria dos engines relacionais e o ponto de partida certo em caso de dúvida.

Recomendação: índice Hash (apenas igualdade)

Um índice hash armazena o hash do valor da coluna e é muito rápido apenas para buscas de igualdade exata ('='). Não suporta buscas por intervalo, ordenação nem prefixo, por isso seu caso de uso é restrito.

Recomendação: índice Bitmap (baixa cardinalidade / DWH)

Um índice bitmap mantém um array de bits para cada valor distinto e combina muito rapidamente várias condições de baixa cardinalidade com AND/OR bit a bit. É forte em cargas com muitas leituras, como data warehousing e relatórios.

Recomendação: GIN / GiST (texto, JSON, array, geometria)

O PostgreSQL tem famílias de índices especializadas para tipos de acesso que um B-tree padrão não consegue tratar. O GIN aponta para muitos componentes dentro de um valor (palavras, chaves JSONB, elementos de array); o GiST se adequa a consultas geométricas/de intervalo/de vizinho mais próximo.

Recomendação: índice parcial / filtrado

Um índice parcial indexa apenas as linhas que satisfazem uma condição (WHERE ...) em vez da tabela inteira. Se as consultas sempre visam o mesmo pequeno subconjunto, o índice fica muito menor e mais rápido, e o custo de gravação cai.

Recomendação: covering index (INCLUDE)

Um covering index contém todas as colunas de que a consulta precisa, permitindo que o engine responda apenas pelo índice, sem visitar a tabela (heap) (index-only scan). Oferece um ganho significativo de velocidade para consultas executadas com frequência que retornam poucas colunas.

Abrir no DBAtlas →