1.Index types
B-tree is the default and correct choice for most cases — equality and range queries (<, <=, =, >=, >, BETWEEN, IN) on sortable data. GIN indexes arrays/JSONB/full-text (containment queries: does this array/document contain X). GiST handles geometric/nearest-neighbor queries. BRIN is a tiny, cheap index for huge tables where a column's values roughly follow physical row order (e.g. an auto-incrementing id or a timestamp).
Key features
- B-tree is the default (CREATE INDEX ON table (column) — no USING clause needed) — correct for the vast majority of equality/range queries
- GIN (Generalized Inverted Index) is for composite/multi-valued data — arrays, JSONB, full-text search — answering "does this contain X" queries
- GiST (Generalized Search Tree) supports geometric data and nearest-neighbor (ORDER BY ... <-> ...) queries
- BRIN (Block Range Index) is a tiny, cheap index for huge tables whose column values correlate with physical row order (e.g. a monotonically increasing id or timestamp)
- Hash indexes support only equality (=) — narrower than B-tree, rarely the right choice since B-tree already handles equality plus everything else
Choosing an index type
- B-tree (default) — equality/range on ordinary columns
- GIN — arrays/JSONB/full-text containment
- GiST — geometric / nearest-neighbor
- BRIN — huge, insertion-ordered tables
Command
CREATE INDEX idx_name ON table_name (column_name); -- B-tree
CREATE INDEX idx_name ON table_name USING GIN (jsonb_column); -- GINB-tree is the default and handles equality/range on ordinary columns; GIN is for arrays/JSONB/full-text containment queries; GiST is for geometric/nearest-neighbor; BRIN is a tiny index for huge, insertion-ordered tables. Every index has a real write cost — add them in response to an observed query pattern, not speculatively.