thecodex.expert · The Codex Family of Knowledge
SQL

Execution Plans

EXPLAIN ANALYZE genuinely runs the query and tells you exactly where the time went — it turns "this feels slow" into a specific, fixable line in the plan.

SQL:2016 / ANSI EXPLAIN ANALYZE Last verified:
Canonical Definition

EXPLAIN, placed before any query, shows the plan the query planner intends to execute — without actually running it — including which scan type it will use on each table and the estimated cost. EXPLAIN ANALYZE goes further: it actually runs the query and reports the real elapsed time and row counts at each step, letting you compare the planner's estimate against reality.

Seq Scan vs Index Scan

A "Seq Scan" (sequential scan) means the engine is reading every row in the table — fine for a small table, a red flag on a large one when a WHERE clause should have let it use an index instead. An "Index Scan" means the query used an index to jump directly to matching rows.

SQLexplain_basic.sql
EXPLAIN SELECT * FROM users WHERE email = 'alice@example.com';

-- without an index on email:
--   Seq Scan on users  (cost=0.00..1834.00 rows=1 width=64)

-- with an index on email:
--   Index Scan using idx_users_email on users  (cost=0.42..8.44 rows=1 width=64)

EXPLAIN ANALYZE: estimated vs actual

The planner's row-count estimate can be wrong, especially on tables whose statistics are out of date — EXPLAIN ANALYZE's "actual" numbers reveal exactly where that mismatch is, which is often the real clue to a slow query.

SQLexplain_analyze.sql
EXPLAIN ANALYZE
SELECT customers.name, COUNT(orders.id)
FROM customers
JOIN orders ON customers.id = orders.customer_id
GROUP BY customers.name;

-- output includes lines like:
--   Hash Join (cost=15.50..45.00 rows=200 width=40) (actual time=0.5..2.1 rows=180 loops=1)
--   -> estimated 200 rows, actually got 180 — reasonably close, planner is trustworthy here

Reading a plan bottom-up

Execution plans are trees, read from the innermost (bottom) operations outward — the deepest indented lines run first, feeding their results up into the operations above them. The step with the highest actual time, or the biggest gap between estimated and actual rows, is usually where to focus optimization effort first.

Sources

1
PostgreSQL Global Development Group. PostgreSQL Documentation, "Using EXPLAIN", postgresql.org/docs/current/using-explain.html.