CodeGym /Cursos /SQL SELF /Indexação de dados JSONB: usando índices GIN e BTREE

Indexação de dados JSONB: usando índices GIN e BTREE

SQL SELF
Nível 34, Lição 1
Disponível

Indexação no PostgreSQL é aquele esquema pra achar dados rapidinho no banco. Se os dados da sua tabela fossem livros, indexar seria tipo o catálogo da biblioteca, que te ajuda a achar o livro certo pelo nome ou autor. Com JSONB, a parada é um pouco mais tricky, porque os dados ficam num formato estruturado, não em linhas e colunas separadas.

Quando os dados JSONB começam a ficar do tamanho de um "livro do Harry Potter, só que sem ilustrações", buscar dentro dessa estrutura pode ficar bem lento. Por exemplo, se você quiser achar todos os pedidos onde a chave "status" tem o valor "delivered", o PostgreSQL vai ter que passar por todos os registros pra fazer a busca. Parece aquele trampo chato que ninguém quer fazer na mão, né?

Aí que entram os índices GIN e BTREE — são tipo os heróis que salvam a gente de ficar esperando a consulta rodar pra sempre!

Tipos de índice pra JSONB

GIN (Generalized Inverted Index)

O índice GIN foi feito especialmente pra lidar com dados estruturados, tipo arrays e objetos, então ele é perfeito pra JSONB. Ele não indexa o objeto inteiro, mas sim as chaves e valores dentro dele. Ou seja, com GIN dá pra achar rapidinho registros que têm certas chaves, valores ou combinações.

Imagina uma coluna JSONB com esses dados:

{"name": "Alice", "age": 25, "city": "Berlin"}

O índice GIN cria uma estrutura interna onde as chaves "name", "age" e "city" ficam ligadas aos seus valores. Então, quando a gente procura "name": "Alice", o PostgreSQL já sabe onde buscar — não precisa varrer a tabela toda.

BTREE

O índice BTREE é mais tradicional. Ele cria uma estrutura ordenada, que deixa fácil achar dados por valores específicos. No caso do JSONB, o BTREE pode ser usado se você busca uma correspondência exata dos dados ou se tem uma chave fixa (tipo, quer comparar o valor do JSONB inteiro).

Se sua coluna tem objetos JSONB assim:

{"name": "Bob", "age": 30}

O índice BTREE pode ser útil se você procura registros onde o objeto inteiro é igualzinho.

{"name": "Bob", "age": 30}

Criando índice pra JSONB

Bora ver como criar um índice GIN. Tudo que você precisa é o comando mágico CREATE INDEX. Olha só:

-- Criando índice GIN pra coluna JSONB
CREATE INDEX idx_jsonb_data ON orders USING GIN (data);

Onde:

  • idx_jsonb_data — nome do índice.
  • orders — nome da tabela.
  • data — coluna com os dados JSONB.

Depois de criar esse índice, as queries que procuram chaves ou valores dentro do JSONB vão rodar bem mais rápido.

Imagina que a gente tem uma tabela orders com a coluna data que guarda JSONB:

id data
1 {"status": "pending", "total": 100}
2 {"status": "delivered", "total": 200}

Query sem índice:

-- Vamos achar todos os pedidos com status "delivered"
SELECT * FROM orders WHERE data @> '{"status": "delivered"}';

Se a tabela for grande, essa query pode demorar. Mas com o índice GIN ela vai rodar bem mais rápido.

Como criar índice BTREE

Pra criar índice BTREE você tem que mudar um pouco o jeito. Na maioria das vezes, pra usar BTREE com JSONB, você precisa dizer que quer indexar só uma parte do objeto. Tipo assim:

-- Criando índice BTREE pra uma chave específica
CREATE INDEX idx_jsonb_total ON orders ((data->>'total'));

Repara no (data->>'total'). Isso pega o valor da chave total do objeto JSONB, e é esse valor que vai ser indexado. Agora, se você procurar pedidos onde total = 100, o PostgreSQL vai usar esse índice.

Exemplo usando os mesmos dados:

id data
1 {"status": "pending", "total": 100}
2 {"status": "delivered", "total": 200}

Query:

-- Achar todos os pedidos onde total = 100
SELECT * FROM orders WHERE data->>'total' = '100';

Com o índice BTREE pra data->>'total', essa query vai rodar bem mais rápido.

Comparando GIN e BTREE

Característica GIN BTREE
O que é indexado? Chaves e valores dentro do JSONB Caminho ou valor específico
Melhor cenário de uso Busca por partes do objeto Busca por valor específico
Performance na criação Mais lento Mais rápido
Performance na busca Mais rápido pra estruturas complexas Mais rápido pra valores fixos
Suporte a operadores @>, ?, `? ,?&`

Se você tem estruturas JSONB complexas e usa bastante operadores tipo @> ou ?, vai de GIN. Se você procura valores ou chaves fixas, BTREE pode ser a melhor escolha.

Pegadinhas e erros comuns ao indexar JSONB

Trabalhar com indexação de JSONB é poderoso, mas tem umas armadilhas que vale ficar ligado.

  1. Falta de índice onde precisa. Se você usa muito dados JSONB nos filtros (WHERE), mas não criou índice, as queries vão ser lentas.
  2. Indexação demais. Se você cria índice pra toda chave possível do JSONB, vai acabar deixando as inserções e updates mais lentos.
  3. Escolha errada do tipo de índice. Se suas queries são complexas e usam operadores tipo @> ou ?, mas você criou índice BTREE, não vai ganhar performance.
  4. Falta de conhecimento dos caminhos. Se você sempre acessa valores aninhados, mas não criou índice pro caminho certo (tipo data->>'some_key'), sua query vai continuar lenta.

Resumo: quando usar cada índice

  • Usa GIN se você tem arrays ou objetos complexos, onde rola muita busca por chaves e valores.
  • Usa BTREE se você procura correspondência exata ou acessa sempre as mesmas chaves.
2
Tarefa
SQL SELF, nível 34, lição 1
Bloqueado
Criação de índice `GIN` para acelerar buscas em dados JSONB
Criação de índice `GIN` para acelerar buscas em dados JSONB
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION