← Concepts

阅读中文版本

GIN Indexes for Composite Values

A GIN index maps many keys per row to the rows containing them, making it the right structure for arrays, JSON documents, and full-text search.

database

Definition

A GIN index, or inverted index, stores an entry for each element inside a composite value such as an array or document, so a query for a single element can find all rows that contain it.

Context and scope

It is the standard index for containment and existence queries over arrays, JSONB columns, and text search vectors.

Common misconceptions

  • a GIN index is a drop-in replacement for a B-tree index
  • GIN makes document writes as cheap as a plain column update

Anti-patterns

  • indexing a frequently updated JSONB column without measuring write cost
  • assuming a GIN index speeds up ordering or range comparisons

Related concepts

Related examples

Authoritative source

https://www.postgresql.org/docs/current/gin.html

Definition

A GIN index, or inverted index, stores an entry for each element inside a composite value such as an array or document, so a query for a single element can find all rows that contain it.

It is the standard index for containment and existence queries over arrays, JSONB columns, and text search vectors. Compared to simpler alternatives, this concept fits best when the trade-off it represents is the one the system actually cares about.

When to use it

A common use case is applying it at the boundary where the cost of getting it wrong is highest, and the scenario usually involves a concrete guarantee the system must uphold. Unlike an ad hoc approach, it makes that guarantee explicit, reviewable, and testable.

How it works

Because one row can map to many keys, GIN supports operators such as containment and overlap that a B-tree cannot, but it is slower to update since every element must be indexed.

Fast update and pending list settings trade write speed against query latency, and periodic vacuum merges pending entries so readers see a consistent index.

Trade-offs and alternatives

GIN answers element queries, not sorted scans; ordering still needs a B-tree or a separate sort, so choose the index per query shape rather than per table. The main drawback is the extra complexity it introduces, so the benefit should clearly outweigh that cost before a team adopts it.

Common misconceptions

A persistent misconception is that a GIN index is a drop-in replacement for a B-tree index. Another is that GIN makes document writes as cheap as a plain column update. For example, an engineer who assumes otherwise may design around a guarantee that does not actually exist, which only becomes obvious under load or failure.

Anti-patterns to avoid

Two recurring anti-patterns are to indexing a frequently updated JSONB column without measuring write cost and to assuming a GIN index speeds up ordering or range comparisons. Both tend to surface as hard-to-debug production issues rather than obvious test failures. Related concepts include Trigram Indexes for Fuzzy Matching, Full-Text Search Vectors, Advisory Locks.