Why This Matters
Different index types excel at different query patterns. The default B-tree isn't always optimal. Using the wrong index type means your query might not use the index at all, falling back to a sequential scan.
The Problem
Incorrect - B-tree for JSONB containment
-- B-tree cannot optimize containment operators
CREATE INDEX products_attrs_idx ON products (attributes);
SELECT * FROM products WHERE attributes @> '{"color": "red"}';
-- Full table scan - B-tree doesn't support @> operator
The Solution
Correct - GIN for JSONB
-- GIN supports @>, ?, ?&, ?| operators
CREATE INDEX products_attrs_idx ON products USING gin (attributes);
SELECT * FROM products WHERE attributes @> '{"color": "red"}';
Index Type Reference
| Type | Best For | Operators |
|---|---|---|
| B-tree (default) | Most queries, ranges, sorting | =, <, >, BETWEEN, IN, IS NULL |
| GIN | Arrays, JSONB, full-text search | @>, ?, ?&, ?|, @@ |
| BRIN | Large time-series tables (10-100x smaller) | =, <, > on naturally ordered data |
| Hash | Equality-only (slightly faster than B-tree for =) |
= only |
Examples
-- B-tree (default): =, <, >, BETWEEN, IN, IS NULL
CREATE INDEX users_created_idx ON users (created_at);
-- GIN: arrays, JSONB, full-text search
CREATE INDEX posts_tags_idx ON posts USING gin (tags);
-- BRIN: large time-series tables (10-100x smaller)
CREATE INDEX events_time_idx ON events USING brin (created_at);
-- Hash: equality-only (slightly faster than B-tree for =)
CREATE INDEX sessions_token_idx ON sessions USING hash (token);
Check Your Project Automatically
Connect your Supabase project to analyze your index types and usage patterns.
Start Supabase Audit