EXPLAIN vs EXPLAIN ANALYZE: Selecting a Low‑Overhead Query Cost Method for MySQL 8.0+
0 reputation · 28 Apr 2022, 22:20 UTC
0 reputation · 28 Apr 2022, 22:20 UTC
Determine a reliable way to capture actual query execution cost in MySQL 8.0+ without jeopardizing live traffic.
EXPLAIN returns optimizer estimates only and adds negligible overhead.EXPLAIN ANALYZE executes the statement, revealing real timing and row counts, but can increase latency and modify data for DML.Whether to restrict EXPLAIN ANALYZE to staging environments or to sample it in production guarded by MAX_EXECUTION_TIME.
Questions:
EXPLAIN ANALYZE workflow sufficient to validate optimizer estimates for the production workload?EXPLAIN ANALYZE is unavailable?35275 reputation · 29 Apr 2022, 04:44 UTC
EXPLAIN returns the optimizer’s plan with virtually zero overhead, so it can run on production traffic without side effects. However, it only estimates rows and cost. Running EXPLAIN ANALYZE on a staging copy lets you see the real execution time, rows examined, and whether the chosen index is actually used. If the staging environment mirrors production in schema, data distribution, and server configuration, the estimates will be highly correlated with production behavior.
performance_schema.events_statements_summary_by_digest to identify hot queries and sample only those.
SET SESSION max_execution_time = 200; -- 200 ms
EXPLAIN ANALYZE SELECT * FROM orders WHERE status = 'shipped';
The statement will abort after 200 ms, limiting latency impact. For DML, wrap in a transaction:
START TRANSACTION;
SET SESSION max_execution_time = 200;
EXPLAIN ANALYZE UPDATE orders SET shipped_at = NOW() WHERE id = 12345;
ROLLBACK;
This guarantees no data changes.
If you cannot run EXPLAIN ANALYZE (e.g., due to strict latency budgets or non‑transactional engines), query the digest table for the same digest:
SELECT digest_text, avg_timer_wait, sum_rows_examined
FROM performance_schema.events_statements_summary_by_digest
WHERE digest_text = 'SELECT * FROM orders WHERE status = ?';
Compare avg_timer_wait (in picoseconds) to the sample average from EXPLAIN ANALYZE. A consistent ratio suggests the digest is representative.
MAX_EXECUTION_TIME and that a rollback leaves data unchanged.
To fine‑tune the recommendation, could you confirm whether the queries you target are read‑only or include DML? Knowing that will determine if transaction wrapping is necessary and whether partial updates could affect the system during sampling.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 29 Apr 2022, 08:03 UTC
When you need real timings but must avoid data changes, run EXPLAIN ANALYZE inside a transaction and roll it back afterward; this works for SELECT, UPDATE, DELETE, and INSERT as long as the engine supports transactional rollback (InnoDB). Combine with the MAX_EXECUTION_TIME optimizer hint to abort long‑running analyses, and note that the hint only affects the statement being explained, not the surrounding transaction.