GIN index
What is a GIN index in PostgreSQL?
A GIN (generalized inverted) index maps each element inside a value, such as an array element, a JSONB key or a text search word, to the rows that contain it.
GIN stands for Generalized Inverted Index. It is designed for composite values, where each indexed item contains several elements, and for queries that look for items containing particular elements. Typical uses are arrays, jsonb and full text search.
With the default operator classes, GIN supports operators such as @> (contains) and && (overlaps) for arrays, and @> plus the key-existence operators for jsonb. Lookups are fast, but inserts and updates cost more than with a B-tree. The fastupdate storage parameter, on by default, buffers new entries in a pending list to soften that cost.
Example
The example indexes a text[] column with GIN and asks EXPLAIN about rows whose tags include t42. The output shows a Bitmap Index Scan on docs_tags_gin.
CREATE TABLE docs (id int PRIMARY KEY, tags text[]);
INSERT INTO docs
SELECT g, ARRAY['t' || (g % 100), 'u' || (g % 7)] FROM generate_series(1, 100000) AS g;
CREATE INDEX docs_tags_gin ON docs USING gin (tags);
ANALYZE docs;
EXPLAIN SELECT id FROM docs WHERE tags @> ARRAY['t42'];Plain SQL for stock PostgreSQL 16 or 17, no extensions needed. Run it in an empty database you can throw away.
Sources
Official PostgreSQL documentation (in English).