High Impact

Create Composite Indexes for Multi-Column Queries

5-10x faster multi-column queries

Why This Matters

When queries filter on multiple columns, a composite index is significantly more efficient than separate single-column indexes. With separate indexes, Postgres must perform a bitmap scan that combines results from multiple indexes - slower and more memory-intensive.

This becomes critical when you have queries like:

The Problem

Incorrect - Separate indexes require bitmap scan
-- Two separate indexes
CREATE INDEX orders_status_idx ON orders (status);
CREATE INDEX orders_created_idx ON orders (created_at);

-- Query must combine both indexes (slower)
SELECT * FROM orders 
WHERE status = 'pending' AND created_at > '2024-01-01';

The Solution

Correct - Single composite index
-- Single composite index (leftmost column first for equality checks)
CREATE INDEX orders_status_created_idx ON orders (status, created_at);

-- Query uses one efficient index scan
SELECT * FROM orders 
WHERE status = 'pending' AND created_at > '2024-01-01';

Column order matters! Place equality columns (=) first, range columns (>, <, BETWEEN) last. The index (status, created_at) works for WHERE status = 'pending' but NOT for WHERE created_at > '2024-01-01' alone.

The Leftmost Prefix Rule

A composite index on (a, b, c) can satisfy queries on:

Check Your Project Automatically

Connect your Supabase project to analyze your indexes and query patterns.

Start Supabase Audit

Common Mistakes

Learn More