Build the mental model
B-tree is the default for equality, ranges, and ordering. GIN commonly supports multi-valued data, JSONB, and text search. GiST suits ranges and geometric operator classes, while BRIN can help very large tables correlated with physical order. Expression and `INCLUDE` columns can help queries but add write cost.
Connect it to a real scenario
Use an expression index on `lower(email)` for case-insensitive lookup and a covering index for the published catalog. Review usage statistics over a representative workload before declaring an index duplicate or unused.
Try the working example
CREATE UNIQUE INDEX users_email_lower_uidx
ON app.users (lower(email));
CREATE INDEX tutorials_catalog_cover_idx
ON app.tutorials (published_at DESC, tutorial_id DESC)
INCLUDE (title, slug)
WHERE is_published = true;
SELECT relname, indexrelname, idx_scan
FROM pg_stat_user_indexes
WHERE schemaname = 'app';You have case-insensitive uniqueness and a covering catalog index.5-minute try-it
Choose index types for JSONB tag containment, an event-date range, and a huge append-only log.
One important caution
Do not drop an index immediately because `idx_scan = 0`; check statistics resets, rare critical queries, and replica workloads.
PostgreSQL — Index Types — PostgreSQL Global Development Group