Model Artifact: Query-Plan Review
Scenario
A Semester 6 learner reviews a slow dashboard query before proposing an index.
Completed learner-quality example
Query purpose
Show the 25 most recent paid orders for one tenant, including customer email and total amount.
Baseline plan summary
Seq Scan on orders (rows=1,240,000)
Filter: tenant_id = $1 AND status = 'paid'
Sort by created_at DESC
Nested Loop to customers by primary key
Limit 25
Problem
The database scans every order for every dashboard load, filters to one tenant and status, sorts the surviving rows, and then keeps only 25. The expensive work happens before the LIMIT can help.
Proposed change
Add a composite index that matches the equality filters first and the ordering second:
CREATE INDEX CONCURRENTLY idx_orders_tenant_status_created_desc
ON orders (tenant_id, status, created_at DESC);
Expected improved plan
Index Scan using idx_orders_tenant_status_created_desc on orders
Index Cond: tenant_id = $1 AND status = 'paid'
Limit 25
Nested Loop to customers by primary key
Tradeoffs
- Write cost increases for order inserts and status updates.
- Index size is acceptable because it supports a high-traffic dashboard path.
- If only paid orders are queried, a partial index on
status = 'paid'may be smaller, but the composite full index also supports admin status filters.
Validation plan
Compare EXPLAIN (ANALYZE, BUFFERS) before and after on staging data, require reduced shared-buffer reads, and verify p95 dashboard latency under representative tenant sizes.
How to read this example
- Passing: Describes the query purpose, current plan, problem, and proposed index.
- Strong: Explains why
LIMITwas ineffective before the index and orders index columns intentionally. - Portfolio-worthy: Includes operational tradeoffs and a validation plan beyond estimated cost.