High Impact

Use Partial Indexes for Filtered Queries

5-20x smaller indexes, faster writes and queries

Why This Matters

Partial indexes only include rows matching a WHERE condition, making them smaller and faster when queries consistently filter on the same condition. This is perfect for:

The Problem

Incorrect - Full index includes irrelevant rows
-- Index includes all rows, even soft-deleted ones
CREATE INDEX users_email_idx ON users (email);

-- Query always filters active users
SELECT * FROM users 
WHERE email = '[email protected]' AND deleted_at IS NULL;

The Solution

Correct - Partial index matches query filter
-- Index only includes active users
CREATE INDEX users_active_email_idx ON users (email)
WHERE deleted_at IS NULL;

-- Query uses the smaller, faster index
SELECT * FROM users 
WHERE email = '[email protected]' AND deleted_at IS NULL;

Key insight: The query's WHERE clause must match or be more restrictive than the index's WHERE clause for Postgres to use the partial index.

Common Use Cases

-- Only pending orders (status rarely changes once completed)
CREATE INDEX orders_pending_idx ON orders (created_at)
WHERE status = 'pending';

-- Only non-null values
CREATE INDEX products_sku_idx ON products (sku)
WHERE sku IS NOT NULL;

-- Only recent data
CREATE INDEX logs_recent_idx ON logs (user_id)
WHERE created_at > '2024-01-01';

Check Your Project Automatically

Connect your Supabase project to identify opportunities for partial indexes.

Start Supabase Audit

Common Mistakes

Learn More