PostgreSQL · Execution plans · DBA-021
How to Read an EXPLAIN Query Plan in PostgreSQL
Understand scan types, row estimates, join operators and the important difference between EXPLAIN and EXPLAIN ANALYZE.
The short answer
Start with plain EXPLAIN to see the plan PostgreSQL expects to use without running the query. Read the plan from the deepest scan nodes upward; check estimated row counts and join methods. Use EXPLAIN (ANALYZE, BUFFERS) only when you intentionally want to execute the statement and measure what happened.
Start with the planned work
Replace the illustrative schema and table with a query from your environment. Plain EXPLAIN produces the estimated plan without performing the underlying table scan.
EXPLAIN
SELECT order_id, customer_id, order_date
FROM sales.orders
WHERE order_date >= DATE '2026-06-01';Example objects such as sales.orders must exist for the query to plan successfully.
Read the most important plan signals
Look for the earliest point where a row estimate differs sharply from the observed row count. A poor estimate can lead to poor choices further up the plan tree.
Measure actual work when it is safe to execute
ANALYZE changes the meaning of the command: the SQL runs. Even a read-only query can consume significant resources on a large production dataset.
EXPLAIN (ANALYZE, BUFFERS)
SELECT order_id, customer_id, order_date
FROM sales.orders
WHERE order_date >= DATE '2026-06-01';For data-modifying statements, EXPLAIN ANALYZE really performs the change. In a controlled test, the book demonstrates wrapping DML in a transaction and rolling it back. Trigger side effects outside the transaction and sequence changes may still remain, so use a test environment where possible.
A practical plan-reading routine
- Observe the innermost scans. What rows enter the plan, and where are filters applied?
- Compare estimates with reality. If running ANALYZE, check
rowsandloopstogether. - Follow rows upward. Watch for unexpected growth across joins or aggregates.
- Look for costly operations. Sorts spilling to disk, heavy nested loops or repeated scans may be clues.
- Investigate the reason. Check statistics, predicates and indexing before assuming any scan type is inherently wrong.
Related DBA tasks
DBA-022 looks for index candidates, DBA-024 updates statistics, DBA-026 identifies costly queries over time, and DBA-028 compares estimated and actual work in depth.
Continue learning · Baldwin Apps
More practical solutions in SQL Recipes for DBAs
Find engine-specific recipes for sessions, locks, performance, permissions, backups, maintenance, and troubleshooting. Explore the book and its existing companion materials.