High Impact

Choose the Right Index Type for Your Data

10-100x improvement with correct index type

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

TypeBest ForOperators
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

Learn More