Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. EXPLAIN: как разбирать медленный запрос
explain_tuning

EXPLAIN: как разбирать медленный запрос

Дерево плана, строки, повторы, буферы, временные файлы и честное сравнение

Открыть лабораториюv1.1.0Запускается локально из публичного репозитория

EXPLAIN: как разбирать медленный запрос

EXPLAIN показывает план, который выбрал PostgreSQL. Обычный EXPLAIN только строит оценку и не выполняет запрос. EXPLAIN ANALYZE действительно выполняет его и добавляет фактические строки и время.

Поэтому EXPLAIN ANALYZE DELETE ... удалит данные, а UPDATE изменит их. Для команд записи используйте отдельную копию базы. Транзакция с откатом подходит только тогда, когда допустимы все временные блокировки, триггеры и внешние побочные действия:

BEGIN; EXPLAIN (ANALYZE, BUFFERS, WAL, SETTINGS, FORMAT JSON) UPDATE marketplace.inventory SET reserved = reserved + 1 WHERE product_id = 1 AND reserved < available; ROLLBACK;

ROLLBACK отменит изменение таблицы, но не отменит отправленный триггером сетевой запрос. Формат JSON удобен для автоматического сравнения планов.

План — это дерево

Нижние узлы получают строки из таблиц и индексов. Верхние фильтруют, сортируют, соединяют и агрегируют результаты. Отступ показывает родителя и ребёнка.

Основные поля узла:

  • actual time=a..b — время до первой и до последней строки;
  • rows=n — число строк за одно выполнение;
  • loops=k — сколько раз узел повторялся;
  • Rows Removed by Filter — сколько строк прочитано, но отброшено условием;
  • Buffers: shared hit — страницы найдены в общем кеше;
  • Buffers: shared read — страницы пришлось прочитать с хранилища;
  • dirtied и written — страницы изменены и записаны;
  • temp read/write — промежуточные данные вышли из памяти во временный файл;
  • WAL records/bytes — объём журнала, созданный изменением.

Время дочернего узла уже входит во время родителя, поэтому складывать времена всех строк плана нельзя. Ищите неожиданно большой объём строк, много повторов, запись временного файла и первую сильную ошибку оценки.

Воспроизводимый эксперимент

Изменение «ускорило запрос со 120 до 80 мс» ещё ничего не доказывает: второй запуск мог прочитать страницы из кеша. Работайте по шагам.

  1. Сохраните текст запроса, значения параметров, версию PostgreSQL, настройки и форму данных.
  2. Отдельно измеряйте холодный и прогретый кеш либо явно прогревайте данные.
  3. Выполните несколько серий и смотрите медиану и медленные значения, а не один удачный запуск.
  4. Измените только один фактор: запрос, статистику или индекс.
  5. Сравните строки, повторы, буферы, временные файлы, WAL и задержку.
  6. Измерьте цену решения для записи и размер новых объектов.

Нет универсального правила «последовательное чтение плохо после 10 000 строк» или «индекс нужен, если выбирается меньше 30%». Важны ширина строки, кеш, физический порядок, скорость диска и одновременная нагрузка.

Частые причины

Оценка строк сильно ошиблась. Обновите статистику, проверьте перекос и связь столбцов, при необходимости создайте расширенную статистику.

Index Only Scan много раз читает таблицу. Посмотрите Heap Fetches, карту видимости, частоту изменений и работу autovacuum.

Вложенный цикл повторяет внутренний узел тысячи раз. Возможно, неверно оценено число строк или отсутствует подходящий путь доступа.

Сортировка или хеш ушли на диск. Сначала сократите набор раньше, проверьте индекс и форму запроса. Только потом локально экспериментируйте с work_mem.

SELECT * читает большие значения. Выберите только нужные столбцы, чтобы не читать и не распаковывать TOAST без необходимости.

Практика

В лаборатории 21 вы сохраните планы JSON до и после изменения и примете решение по чтениям и оценкам, а не по одному времени.

Подробнее: использование EXPLAIN.

Проверьте свои знания

Вопросы ещё не добавлены

Вопросы для этой подтемы ещё не добавлены.

Далее: Индексы: ускорение чтения и его цена