EXPLAIN лише оцінює план. EXPLAIN ANALYZE виконує запит і показує поруч з оцінками реальність: фактичний час кожного вузла і скільки рядків він насправді повернув.
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE status = 'pending' ORDER BY created_at LIMIT 20;
Limit (actual time=812.4..812.5 rows=20 loops=1)
-> Sort (actual time=812.4..812.4 rows=20 loops=1)
Sort Method: top-N heapsort
-> Seq Scan on orders (rows=1200 ... actual rows=950000 loops=1)
Filter: (status = 'pending')
Rows Removed by Filter: 4050000
Buffers: shared read=73000
На що дивитися:
- Оцінка проти факту:
rows=1200очікувалося,actual rows=950000вийшло. Велика розбіжність означає застарілу статистику (ANALYZE orders) або корельовані колонки - і планувальник обирає поганий план. Rows Removed by Filter- база прочитала мільйони рядків, щоб відкинути більшість. Підказка до індексу.loops- скільки разів виконувався вузол. Час у вузлі вказано за один прохід: 0.5 мс × 20 000 loops у Nested Loop - це 10 секунд.BUFFERS- скільки сторінок прочитано з кешу (hit) і з диска (read).
Обережно: EXPLAIN ANALYZE справді виконує запит. Для UPDATE/DELETE загортайте його в транзакцію з ROLLBACK.
MySQL має EXPLAIN ANALYZE з версії 8.0.18 - вивід у вигляді дерева з фактичним часом.