EXPLAIN and EXPLAIN ANALYZE reveal BigQuery’s execution plan, showing stage order, slot usage, and estimated/actual costs so you can optimize queries.
An execution plan is BigQuery’s blueprint for running your SQL. It lists each stage, the number of input rows, slot time consumed, and shuffle behavior. Reading it lets you spot scans, joins, and expensive shuffles before or after a query runs.
Prefix your statement with EXPLAIN
.BigQuery returns a JSON-formatted plan without executing the query, so you see estimates only.
Use EXPLAIN ANALYZE
. BigQuery executes the query, then adds runtime statistics—actual rows read, slot-ms, and timing—for every stage.
Use OPTIONS
to tweak behavior. For example, EXPLAIN OPTIONS(max_result_rows=20, format="text")
limits output rows and switches from JSON to a tabular view.
Use EXPLAIN
early in development to check cost without spending slots.Switch to EXPLAIN ANALYZE
when you need real numbers on a finalized query or to compare optimization attempts.
Start at the bottom stage—this is the first operation. Identify full-table scans on large tables and add partitions or filters. Check join stages for broadcast vs shuffle; prefer broadcast on small lookup tables. Watch for high slot-ms; reduce by pruning columns and partitions.
Ignoring estimated row counts: Large estimates mean higher cost.Add WHERE order_date >= CURRENT_DATE()-30
to restrict.
Using ANALYZE on huge ad-hoc queries: It runs the entire job, incurring cost. Start with plain EXPLAIN
.
The query below checks customer lifetime value. We show both estimated and actual plans.
-- Estimate
EXPLAIN
SELECT c.id,
SUM(o.total_amount) AS lifetime_value
FROM Customers c
JOIN Orders o ON o.customer_id = c.id
GROUP BY c.id;.
-- Actual runtime stats
EXPLAIN ANALYZE
SELECT c.id,
SUM(o.total_amount) AS lifetime_value
FROM Customers c
JOIN Orders o ON o.customer_id = c.id
GROUP BY c.id;
No, EXPLAIN returns metadata only. Only ANALYZE runs the job.
Check that the filter uses the partition column directly and is not wrapped in functions.
Click “Save Results” in the BigQuery UI or call the REST API’s jobs.getQueryResults
with the job ID.
Yes. Both Standard and Enterprise editions include it without extra cost.
No. Tune query hints (JOIN BCAST
) in the SQL, then re-run EXPLAIN to verify the change.
Use OPTIONS(max_result_rows=<n>)
to truncate result rows.