EXPLAIN ANALYZE executes a query, then returns the planner’s execution plan plus real-time statistics so you can find and fix slow steps.
EXPLAIN ANALYZE runs the statement and prints the chosen execution plan with actual timing, row counts, and loops, letting you spot bottlenecks immediately.
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM Customers;
The ANALYZE flag adds runtime stats; BUFFERS shows shared/local/temp hits and reads.
Every plan node lists estimated cost, estimated rows, actual rows, loops, and time.Large gaps between estimates and actuals signal outdated statistics or poor indexes.
FORMAT JSON returns a machine-readable plan that works well with visualizers such as pgAdmin or explain.depesz.com.
EXPLAIN (ANALYZE, BUFFERS)
SELECT c.name,
SUM(oi.quantity * p.price) AS total_spent
FROM Customers c
JOIN Orders o ON o.customer_id = c.id
JOIN OrderItems oi ON oi.order_id = o.id
JOIN Products p ON p.id = oi.product_id
WHERE o.order_date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY c.name
ORDER BY total_spent DESC
LIMIT 10;
If the plan shows a sequential scan on Orders
, create an index on (order_date)
or a composite index with customer_id
.
1) Test on production-like data.2) Compare estimates to actuals. 3) Use auto_explain
for automatic capture of slow plans. 4) Validate statistics with ANALYZE
.
VERBOSE displays internal target-list and predicate details, useful for diagnosing sub-query push-down or CTE inlining.
.
Yes, because it actually executes the statement. Wrap DML inside a transaction and roll back when testing.
Use auto_explain
or ">" redirect in psql to save plans, or insert pg_store_plans
extension to keep history.
Outdated statistics, non-uniform data distribution, or enable_*
planner flags can skew estimates. Run ANALYZE
or create extended statistics.