Indexing JSONB with GIN
Build GIN indexes on JSONB documents and use jsonb_path_ops for fast containment queries.
Why GIN for JSONB
JSONB documents have many "items" (key/value pairs and array elements). GIN (Generalised Inverted Index) is built for "rows where document contains X" queries.
Default GIN Index
The default operator class supports @>, ?, ?|, ?&:
CREATE INDEX events_data_gin ON events USING GIN (data);
-- These now use the index:
SELECT * FROM events WHERE data @> '{"type":"login"}';
SELECT * FROM events WHERE data ? 'error';