Logo

dev-resources.site

for different kinds of informations.

POSTGRESQL - ÍNDICE GIN NA PRÁTICA

Published at
1/9/2025
Categories
postgressql
database
learning
performance
Author
mateus-rauli
Author
12 person written this
mateus-rauli
open
POSTGRESQL - ÍNDICE GIN NA PRÁTICA

Hoje vim relatar minha experiência com o índice GIN, que resultou numa melhora muito positiva na performance de algumas das consultas mais lentas do sistema que atuei.

Introdução ao GIN INDEX

O GIN (Generalized Inverted iNdex) é um índice designado para lidar com tipos de dados que são subdivisíveis, ou seja, podem ser "divididos" em partes menores, permitindo a pesquisa de valores individuais. É muito utilizado para consultas em dados estruturados e não estruturados como array, jsonb e campos de texto para busca full-text.

Introduzido na versão 8.2 do PostgreSQL, rapidamente se tornou uma solução indispensável para cenários onde se precisa de buscas rápidas em dados complexos. Diferente do índice padrão B-TREE que é mais adequado para buscas de valores únicos, o GIN é otimizado para casos onde o mesmo valor pode estar associado a vários registros, assim como os valores de um array.

Como eu utilizei o GIN INDEX

Certo dia, me deparei com um problema crítico no sistema: uma consulta estava causando uma lentidão significativa e prejudicando o desempenho geral da aplicação. Após analisar, percebi que ela fazia uso de uma coluna do tipo ARRAY em seu filtro.

Consultando a documentação oficial do PostgreSQL, encontrei o índice GIN como uma possível solução. Decidi implementá-lo na coluna problemática para avaliar o impacto. O resultado foi impressionante: o tempo de execução da consulta caiu drasticamente e, com isso, o sistema se tornou visivelmente mais ágil.

O impacto foi ainda maior porque a coluna onde apliquei o índice GIN era amplamente utilizada em diversas partes do sistema, tornando essa melhoria um divisor de águas para a performance geral. Essa experiência reforçou minha percepção de por que o GIN é frequentemente chamado de "índice mágico".

Desvantagens da utilização do GIN Index

Como visto até então, o índice traz sim diversas vantagens quando o assunto é lidar com dados complexos, porém nem tudo é perfeito e ele possui desvantagens que devem ser consideradas e analisadas caso você esteja pensando em implementar ele na sua tabela.

Uma grande desvantagem são as operações de escrita que se tornam mais custosas já que o índice deve se atualizar para refletir as mudanças dos dados, ou seja, cada operação que altera o dado exige a atualização do índice também, o que é mais custoso em tabelas que possuem alta frequência de escrita.

Além disso, o GIN consome mais memória do que os outros índices, tanto de armazenamento quanto de consulta, especialmente se a coluna indexada contiver muitos valores únicos ou complexos.

Exemplo de criação do índice

Para poder exemplificar o uso do índice, criei uma tabela chamada users contendo apenas id e data.

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    data JSONB
);
Enter fullscreen mode Exit fullscreen mode

Para criarmos o índice, basta usar o USING indicando qual o tipo de índice que será utilizado

CREATE INDEX idx_data_gin ON users USING gin (data);

Pronto! Índice criado, agora ao analisar a consulta será possível notar que ele utilizara o índice criado para buscar a informação.

Query plan
"Bitmap Heap Scan on users u  (cost=12.00..16.01 rows=1 width=68) (actual time=0.022..0.023 rows=1 loops=1)"
"  Recheck Cond: (data @> '{""name"": ""Mateus""}'::jsonb)"
"  Heap Blocks: exact=1"
"  ->  Bitmap Index Scan on idx_data_gin  (cost=0.00..12.00 rows=1 width=0) (actual time=0.011..0.011 rows=1 loops=1)"
"        Index Cond: (data @> '{""name"": ""Mateus""}'::jsonb)"
"Planning Time: 0.120 ms"
"Execution Time: 0.061 ms"
Enter fullscreen mode Exit fullscreen mode

Note que você sempre verá Bitmap Index Scan no plano de execução pois este é o plano de varredura compatível com o índice GIN. Ou seja, isso não significa que seu índice está sendo usado de maneira ineficiente, apenas que é o comportamento esperado.

GIN Multicoluna, uma alternativa para B-TREE x GIN

Em consultas que envolvem colunas com características distintas, pode ser necessário combinar índices B-TREE e GIN. Uma abordagem inicial seria criar índices separados, com um índice B-TREE para colunas que lidam bem com valores únicos e um índice GIN para colunas com dados mais complexos. Embora essa solução funcione, ela pode não ser eficiente em termos de desempenho, pois cada índice é avaliado separadamente.

Uma alternativa interessante é o uso de índices GIN multicoluna. Com essa abordagem, é possível indexar várias colunas em um único índice, cobrindo diferentes tipos de dados. No entanto, para colunas que não são subdivisíveis (como integer ou timestamp), é necessário habilitar a extensão btree_gin do PostgreSQL. Essa extensão permite que esses tipos sejam indexados de maneira compatível dentro de um índice GIN.

CREATE EXTENSION btree_gin;
CREATE INDEX ON records USING gin (data, customer_id);
Enter fullscreen mode Exit fullscreen mode

Com esses comandos você consegue criar um índice GIN multicoluna.

Embora seja uma solução menos comum, ela pode ser útil em cenários específicos. No entanto, é importante considerar que índices maiores resultam em maior uso de I/O e custos adicionais em operações de escrita, como inserções e atualizações.

Considerações finais

Com grandes poderes, vem grandes responsabilidades.

Embora o GIN seja extremamente eficiente em cenários específicos, ele não é uma solução universal para todos os problemas relacionados à performance de consultas. Em muitos casos, o tradicional B-TREE continua sendo a escolha mais adequada, especialmente para consultas simples ou quando se busca por valores únicos. É essencial avaliar cuidadosamente o problema em questão para determinar se a inclusão de um índice é realmente necessária e, caso seja, qual o tipo de índice que melhor atenderá às necessidades do sistema.

Referências

https://www.postgresql.org/docs/current/gin.html
https://pganalyze.com/blog/gin-index

postgressql Article's
30 articles in total
Favicon
GraphDB for CMDB
Favicon
Not able to connect to PostgreSQL server on Fedora
Favicon
Master Test Data Generation With dbForge Studio for PostgreSQL
Favicon
Exploring the Power of Full-Stack Development with Next.js and Prisma
Favicon
Bringing PostgreSQL Query Issues to Light with Insightful Visuals
Favicon
POSTGRESQL - ÍNDICE GIN NA PRÁTICA
Favicon
Reading PostgreSQL Query Plans Brought to a New Level
Favicon
Understanding PostgreSQL Isolation Levels
Favicon
How to Activate and Enable the PostgreSQL Service on Your Kali Linux System
Favicon
Mastering charts and database visualization with ChartDB
Favicon
The Best Ways to Connect to a PostgreSQL Database
Favicon
Hey, welcome to my blog
Favicon
How to Create a Database and Always Connect to It in PostgreSQL Without Needing Superuser Access
Favicon
03. ரிலேஷனல் டேட்டாபேஸ் மாடல் என்றால் என்ன? What is Relational Database Model ? (RDBMS)
Favicon
04. தரவு ஒருங்கிணைவு (Data Integrity)
Favicon
02. DBMS என்றால் என்ன? What is a DBMS?
Favicon
How To Use Materialized Views
Favicon
PostgreSQL Secrets You Wish You Knew Earlier
Favicon
Reading Parallel Plans Correctly
Favicon
New PostgreSQL ORM for Golang: Enterprise
Favicon
Migrate 🪳Coackroach DB into Postgres🐘
Favicon
💡 Database Development: It’s Not Just About Querying!
Favicon
Building Real-Time Data Pipelines with Debezium and Kafka: A Practical Guide
Favicon
01. தரவுத்தளம் எவ்வாறு உருவானது, அதன் தேவை என்ன? How did the database come about, What is its need?
Favicon
Data inconsistency in AWS Amazon Aurora Postgres solved with Local Write Forwarding?
Favicon
PostgreSQL vs. MySQL
Favicon
How To Handle Custom S/DQL Queries On Different Database Engine with DoctrineExpression
Favicon
Deploying PostgreSQL on Kubernetes: 2024 Guide
Favicon
Step-by-Step Guide to Installing PostgreSQL on Arch Linux
Favicon
Remedy for Poor-Performing SQL Queries

Featured ones: