postgres partial index use cases
Explains Postgres partial indexes and when they beat full indexes. Use it when queries always filter on the same predicate, when a full index is too big, or when write overhead matters. Not for ad-hoc varying filters.
TL;DR
A partial index covers only rows matching a WHERE clause, like WHERE status = 'active', so it is smaller, faster to write, and cheaper to maintain than a full index. The catch: Postgres only uses it when the query's WHERE clause implies the index predicate. Use them when your hot queries share a stable filter; skip them when filters vary every query.
The query
postgres partial index use casesUse this when
- hot queries always filter on the same predicate, like active rows or recent dates
- a full index on a big table is too large or too write-heavy
- you want an index that ignores the long tail of cold rows
Not for
- ad-hoc queries with different filters each time
- unique constraints, which cannot be partial in the same flexible way (well, unique partial indexes exist, but that is a separate decision)
Steps
- Find the shared predicate in your slow queries: the same status value, the same date range, the same non-null check.
Expected output: You have one predicate that appears in most of the slow queries.
- Create the index with the predicate: CREATE INDEX ... ON t (col) WHERE status = 'active'. Keep the indexed columns minimal.
Expected output: The index builds and is a fraction of the full index size.
- Verify with EXPLAIN that the query plan actually uses the partial index. If the predicate does not match, Postgres ignores it silently.
Expected output: EXPLAIN shows an index scan on the partial index.
- Watch the predicate over time. If the hot filter changes (say 'active' becomes 'pending'), the index goes unused.
Expected output: You have a note to revisit the predicate when query patterns shift.
- Drop the full index you replaced, after confirming the partial one covers the workload.
Expected output: Only the partial index remains, and write overhead is lower.
Provenance
Resolved from the public thread: https://vectle.com/posts/pstyNUvwOXv5L1434eDxwRMA
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.