Section 1 of 3 · 7 minutes
Read a plan from the inside out
Your goal
What you will be able to do
Identify scans, joins, estimates, and the data flow through a PostgreSQL query plan.
Why this matters at work
The practical reason
The slow part may be a child scan or join rather than the final operation shown at the top.
Learn
The idea in plain English
`EXPLAIN` shows the plan PostgreSQL chose without running the statement. Each indented node produces rows for its parent. Read the deepest scans first, then follow rows upward through joins, sorts, and aggregates.
Cost values are planner units, not milliseconds. Estimated rows are especially important because a large error can lead PostgreSQL to choose the wrong join or scan method.
Remember these points
- Child nodes feed rows into parent nodes.
- Planner cost is not elapsed time.
- Large row-estimate errors can change the chosen plan.
See it in SQL
View a plan without running the query
Inspect the planned access path safely before collecting runtime measurements.
EXPLAIN
SELECT customer_id, count(*)
FROM training_orders
WHERE created_at >= current_date - interval '30 days'
GROUP BY customer_id;This plan may show a table scan or index scan feeding an aggregate. The chosen path depends on table size, statistics, and how much of the table falls in the date range.
Because plain EXPLAIN does not run the query, it is useful for checking potentially expensive or changing statements before execution.
A tree of plan nodes with estimated costs and row counts, without executing the SELECT.
Useful words
Important terms
- Plan node
- One operation in an execution plan, such as a scan, join, sort, or aggregate.
Quick check · Not graded
Check your understanding
What do the cost numbers in EXPLAIN represent?
Your progress is saved to your signed-in account.