EXPLAIN ANALYZE действительно выполняет UPDATE: как исследовать запись
Нужно понять, почему массовое обновление работает медленно. Разработчик привык добавлять EXPLAIN ANALYZE перед SELECT и делает то же перед UPDATE в рабочей базе. Команда выводит красивый план, но данные уже изменились: слово EXPLAIN не сделало операцию предварительным просмотром.
Без ANALYZE PostgreSQL строит план, а с ANALYZE запускает запрос и измеряет исполнение. Это относится к записывающим командам тоже. Для исследования транзакционных изменений удобно использовать отдельный тестовый стенд; ROLLBACK помогает вернуть обычные изменения таблиц при локальном опыте.
Как изменить решение
BEGIN;
EXPLAIN (ANALYZE, BUFFERS)
UPDATE order_stage
SET processed = true
WHERE processed = false;
ROLLBACK;План покажет реальные строки и обращения к буферам, а откат отменит изменения processed в таблице. Команда всё равно выполняла работу, брала блокировки и создавала нагрузку. Это принципиально отличается от EXPLAIN без ANALYZE.
Если UPDATE вызывает триггеры, изучите их до запуска. Побочные действия вне транзакционной базы и продвижение sequence нельзя считать автоматически отменёнными. Для плана потенциально тяжёлой записи сначала используйте обычный EXPLAIN, затем воспроизводимый набор данных в отдельной среде.
Что проверить на своих данных
Запомните количество строк с processed = false, выполните опыт и после ROLLBACK посчитайте снова. Для чтения плана сравните оценку rows с actual rows, проверьте loops и время узлов. Числа actual rows при нескольких loops показываются в расчёте на один цикл; без этого легко недооценить работу вложенного цикла.
Не складывайте времена всех узлов: родительское время включает работу дочерних узлов. И не делайте вывод по одной строке Seq Scan. Для обновления значительной части таблицы последовательное чтение может быть разумным. Ищите место, где объём или повторение работы расходится с ожиданием, затем меняйте запрос и повторяйте замер на сопоставимом состоянии данных.
Практика дальше
Следующая практика — запросы, где правильность зависит от нескольких источников и граничных случаев. В курсе «Продвинутый SQL» вы решаете 109 задач на JOIN, окна и CTE, сверяете отчёты и собираете витрину интернет-магазина. Запросы выполняются в браузере на SQLite с автоматической проверкой.
Посмотреть программу и практику курса
Источник: EXPLAIN ANALYZE действительно выполняет UPDATE — официальная документация.
Другие задачи по теме: PostgreSQL: запись, блокировки и планы запросов.
Продолжить на практике
- Продвинутый SQL: сложные запросы и задачи для собеседований ↗
Продолжение базового SQL: сложные JOIN, оконные рамки, временные ряды, retention, воронки и рекурсивные CTE. Разбирайте примеры и пишите запросы с автоматической проверкой — от отдельных расчётов до витрины интернет-магазина.
