postgresql_partial_indexes_jsonb 22 Q&As

PostgreSQL Partial Indexes Jsonb FAQ & Answers

22 expert PostgreSQL Partial Indexes Jsonb answers researched from official documentation. Every answer cites authoritative sources you can verify.

indexing_strategies

22 questions
A

Indexes with WHERE clause that index subset of rows. For JSONB: index only rows matching specific JSON criteria. Example: CREATE INDEX ON orders USING GIN ((data -> 'items')) WHERE data->>'status' = 'pending'. Smaller index size (50-90% reduction), faster queries on filtered data, lower maintenance cost.

99% confidence
A

Unique partial index for conditional uniqueness: CREATE UNIQUE INDEX ON users ((data->>'email')) WHERE data->>'email' IS NOT NULL. Enforces uniqueness only for non-null emails. Smaller index than full GIN. Upsert: INSERT ... ON CONFLICT ((data->>'email')) WHERE data->>'email' IS NOT NULL DO UPDATE. 30-50% faster than full unique index.

99% confidence
A

Pitfalls: (1) Query WHERE must match index WHERE exactly (planner won't use index if different), (2) Overly specific WHERE (index too small, poor selectivity), (3) Multiple partial indexes on same column (planner confusion), (4) Forgetting to update queries when adding partial index, (5) Index bloat if filter condition drifts over time.

99% confidence
A

Partial indexes reduce vacuum overhead: smaller index = faster vacuum. autovacuum triggers when % of indexed rows change (not total rows). Example: partial index on 10% of table triggers autovacuum at lower absolute row count. Monitor: pg_stat_user_tables.n_tup_ins/upd/del vs pg_stat_user_indexes.idx_scan ratio.

99% confidence
A

Per-tenant partial indexes: CREATE INDEX idx_tenant_123 ON events USING GIN (data) WHERE tenant_id = 123. For 100 tenants: 100 small indexes vs 1 huge index. Trade-off: more indexes (metadata overhead) vs faster tenant queries. Use when: <1000 tenants, tenant queries dominate, each tenant <10% of data. Consider partitioning for >1000 tenants.

99% confidence
A

Migration steps: (1) CREATE partial index CONCURRENTLY, (2) Verify query plans use new index (EXPLAIN), (3) Monitor pg_stat_user_indexes for both indexes, (4) Drop old full index: DROP INDEX CONCURRENTLY old_idx. CONCURRENTLY prevents locking during creation/drop. Rollback: old index still exists until step 4. Test on replica first.

99% confidence
A

Indexes with WHERE clause that index subset of rows. For JSONB: index only rows matching specific JSON criteria. Example: CREATE INDEX ON orders USING GIN ((data -> 'items')) WHERE data->>'status' = 'pending'. Smaller index size (50-90% reduction), faster queries on filtered data, lower maintenance cost.

99% confidence
A

Unique partial index for conditional uniqueness: CREATE UNIQUE INDEX ON users ((data->>'email')) WHERE data->>'email' IS NOT NULL. Enforces uniqueness only for non-null emails. Smaller index than full GIN. Upsert: INSERT ... ON CONFLICT ((data->>'email')) WHERE data->>'email' IS NOT NULL DO UPDATE. 30-50% faster than full unique index.

99% confidence
A

Pitfalls: (1) Query WHERE must match index WHERE exactly (planner won't use index if different), (2) Overly specific WHERE (index too small, poor selectivity), (3) Multiple partial indexes on same column (planner confusion), (4) Forgetting to update queries when adding partial index, (5) Index bloat if filter condition drifts over time.

99% confidence
A

Partial indexes reduce vacuum overhead: smaller index = faster vacuum. autovacuum triggers when % of indexed rows change (not total rows). Example: partial index on 10% of table triggers autovacuum at lower absolute row count. Monitor: pg_stat_user_tables.n_tup_ins/upd/del vs pg_stat_user_indexes.idx_scan ratio.

99% confidence
A

Per-tenant partial indexes: CREATE INDEX idx_tenant_123 ON events USING GIN (data) WHERE tenant_id = 123. For 100 tenants: 100 small indexes vs 1 huge index. Trade-off: more indexes (metadata overhead) vs faster tenant queries. Use when: <1000 tenants, tenant queries dominate, each tenant <10% of data. Consider partitioning for >1000 tenants.

99% confidence
A

Migration steps: (1) CREATE partial index CONCURRENTLY, (2) Verify query plans use new index (EXPLAIN), (3) Monitor pg_stat_user_indexes for both indexes, (4) Drop old full index: DROP INDEX CONCURRENTLY old_idx. CONCURRENTLY prevents locking during creation/drop. Rollback: old index still exists until step 4. Test on replica first.

99% confidence