Базы данных

Запрос тормозит? Визуализация плана EXPLAIN покажет почему

Читать сырой план EXPLAIN утомительно. Вставьте его в LetDraw, чтобы визуализировать план EXPLAIN и увидеть, как медленная часть подсвечивается.

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

Эта стена текста: план EXPLAIN, и в нём весь ответ. База данных точно сообщает, как она выполнит ваш запрос, узел за узлом, со стоимостью на каждом. Проблема в формате. Сырой план плотный, глубоко вложенный и оптимизирован для парсера, а не для человека, читающего его в пятницу в четыре часа дня. Поэтому большинство из нас ищет глазами слова «Seq Scan», чувствует смутную тревогу и идёт дальше.

Дерево плана запроса, которое притворяется текстом

Любой план EXPLAIN на самом деле дерево. Корень: итоговый результат, его потомки: шаги, которые его питают, и у каждого шага есть оценка стоимости. Когда вы выводите его текстом, эта структура сплющивается в отступы, и единственное, что вас на самом деле интересует (куда уходит время), тонет среди строк, ширин и счётчиков циклов.

Решение: перестать читать дерево как текст и начать видеть его как дерево. Сначала запросите формат, удобный для машины:

psql
-- Postgres: ask for JSON so the plan keeps its structure
EXPLAIN (ANALYZE, FORMAT JSON)
SELECT u.name, count(o.id)
FROM users u
JOIN orders o ON o.user_id = u.id
WHERE o.created_at > '2026-01-01'
GROUP BY u.name;

Postgres (и MySQL со своим FORMAT=JSON) ответит JSON-документом вместо обычного текста. Он выглядит так, и, честно говоря, читать его вручную ненамного приятнее:

plan.json
[{ "Plan": {
  "Node Type": "Hash Join",
  "Total Cost": 18422.6,
  "Plans": [
    { "Node Type": "Seq Scan",
      "Relation Name": "orders",
      "Total Cost": 15903.0 },
    { "Node Type": "Index Scan",
      "Relation Name": "users",
      "Total Cost": 211.4 }
  ] } }]

Вставьте план, и медленная часть подсветится

Скопируйте этот JSON, откройте в LetDraw диалог «Создать из кода» и вставьте. Не нужно объяснять, что это такое. LetDraw сам распознаёт план EXPLAIN из Postgres или MySQL и отображает его как дерево плана с тепловой картой: настоящее дерево, нарисованное целиком, где каждый узел окрашен по своей стоимости.

Самый дорогой узел: самый красный. Вот и весь разбор, одним взглядом.

Горячие узлы светятся красным и оранжевым; дешёвые остаются зелёными. Поэтому вместо того чтобы разбирать стоимости глазами, вы смотрите на картинку, и внимание сразу идёт к узкому месту.

Hash Join cost 18422 Seq Scan orders cost 15903 Index Scan users cost 211 чтение таблицы индекс, дёшево
Тот же план в виде дерева. Красный Seq Scan по orders делает почти всю работу; сторона users уже покрыта индексом.

Теперь диагноз очевиден. Сторона orders: это Seq Scan, полное чтение таблицы, тогда как users уже обслуживается через Index Scan. Дорогой hash join наверху дорог потому, что его питает это полное сканирование. Недостающий индекс на orders(created_at) вы не вычислили по столбцу стоимости; это единственный красный блок на странице.

Ваш медленный запрос не покидает браузер

Об этом специалисты по базам данных обычно спрашивают первым делом. План EXPLAIN может раскрыть имена таблиц, имена столбцов и оценки числа строк, которые не хочется отдавать случайному веб-инструменту. LetDraw делает всё на стороне клиента. Парсинг и раскладка происходят в вашем браузере, на вашей машине. Ничего о вашем запросе или схеме не загружается на сервер ради картинки.

  • Вставляйте план из продакшен-базы, и он не покинет ваш ноутбук
  • Чтобы превратить план в дерево, не нужны ни аккаунт, ни загрузка
  • Та же приватность действует и в облачном приложении, и при самостоятельном хостинге
Совет. Используйте EXPLAIN (ANALYZE), когда можете позволить себе реально выполнить запрос. Стоимости превращаются в измеренное время вместо оценок, и тепловая карта показывает, куда время действительно ушло, а не только куда его предполагал планировщик.

Это диаграмма, значит, с ней можно работать

Дерево плана: не статичная картинка. Оно состоит из тех же редактируемых фигур, что и всё остальное в LetDraw, поэтому, как только вы заметили проблему, её можно превратить в то, что поймёт коллега.

  • Обведите горячий путь и оставьте заметку о недостающем индексе
  • Вставьте планы «до» и «после» рядом, чтобы показать, что исправление сработало
  • Экспортируйте в PNG, SVG или PDF и приложите к пул-реквесту или разбору инцидента

Сырой план расшифровывает один инженер в одиночку. Дерево с тепловой картой и заметкой на красном блоке всё ревью понимает за несколько секунд. В этом разница между «запрос медленный» и «вот медленная часть, а вот исправление в одну строку». Вставьте ваш следующий план EXPLAIN, и пусть узкое место представится само.

Посмотрите, на что ваш запрос тратит время

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

Открыть LetDraw бесплатно