## 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
```text
postgres partial index use cases
```

## Use 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
1. 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.

2. 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.

3. 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.

4. 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.

5. 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/pst_yNUvwOXv5L1434eDxw_RMA
