Сорок секунд: первый EXPLAIN ANALYZE

Отчёт, который завис

12 min
What you'll learn
  • видеть путь запроса после Enter: → исполнитель
  • понимать, что SQL описывает результат, а маршрут к нему выбирает машина
  • почувствовать медленный запрос руками — на журнале в сто восемьдесят тысяч строк
  • открывать чертёж запроса — его план — ДО того, как чинить: это делает команда EXPLAIN, с ней и знакомимся

Глава 1 — «Сорок секунд»

Утро на «Хранилище-9» начинается с отчёта жизнеобеспечения: сводка по палубам уходит коменданту в шесть ноль-ноль. Сегодня она не ушла.

Ты открываешь журнал: запрос, который месяцами собирался мгновенно, шёл сорок секунд. Станция не изменилась. Запрос не изменился. Изменился архив: журнал жизнеобеспечения дописал четверть миллиона показаний — и старые запросы начали ползти.

Первый рефлекс любого курсанта: «медленно — значит, нужен ». Останови его. Индекс, поставленный вслепую, — это лекарство, выписанное без диагноза: иногда помогает, иногда бесполезно, а иногда делает хуже.

КВЕРИ: Сорок секунд — это не поломка. Это симптом. Пойдём вниз — покажу, где у станции решают, каким путём пойдёт твой запрос.

КВЕРИ открывает люк, который ты считал декорацией. Под жилыми палубами — машинное отделение: гул, тепло и ровные ряды механизмов. Здесь каждый твой запрос превращается в маршрут по данным. И сегодня ты впервые увидишь этот маршрут своими глазами.

A floor hatch stands open in a quiet deck: ember light and steam pour up, an unfinished report and a stopped clock sit on a desk, the cadet climbs down the ladder into the engine room, the robotic cat waiting on the bottom rung and a clockwork brass parrot perched on the rail.
Forty seconds isn't a breakdown, it's a symptom. The cause lives one deck below, where the route of a query gets decided.

Что происходит с запросом после Enter

SQL — декларативный язык: ты описываешь, что хочешь получить, и ни слова о том, как это сделать. «Как» решает база — за три шага:

  1. Парсер читает текст запроса и превращает его в структуру: какие таблицы, какие условия, какие колонки.
  2. Планировщик перебирает возможные маршруты — прочитать таблицу целиком или пойти по индексу, в каком порядке соединять таблицы, каким алгоритмом — и по своей модели стоимости выбирает самый дешёвый.
  3. Исполнитель едет по выбранному маршруту и собирает строки.

Один и тот же вопрос можно исполнить десятками маршрутов, и разница между ними — не проценты, а порядки: тот же результат за миллисекунды или за минуты.

Планировщик — это и есть машина, к которой мы спустились. Она не видит твоих намерений — только запрос, схему и свои карты данных. Весь этот курс — о том, как понимать её решения и влиять на них.

КВЕРИ: Я зову её штурманом. Штурман не бывает «глупым» — бывают устаревшие карты и нечитаемые приказы. И то и другое чинится.

The path of a query: the parser reads the text, the planner picks the route, the executor drives it

Почувствуй сорок секунд

Вот уменьшенная копия того самого отчёта: для каждого датчика первых пяти палуб — сколько показаний он прислал за всё время. Журнал ls_readings держит сто восемьдесят тысяч строк, и для КАЖДОГО из двухсот датчиков запрос заново пролистывает его целиком.

Запусти и не отводи глаз от таймера:

Двести датчиков — и двести полных проходов по журналу. На настоящем отчёте станции таких проходов были тысячи: вот откуда сорок секунд.

Чертёж до рейса

Секунды таймера говорят «плохо», но не говорят почему. Чтобы увидеть причину, у машины есть команда EXPLAIN: покажи маршрут, который выбрал штурман, — не выполняя запрос.

EXPLAIN <твой запрос>;

В ответ приходит план — дерево операций, тот самый чертёж маршрута. Слово читается «эксплейн», и запомнить его стоит сразу: другой команды, показывающей решение штурмана, у нас нет. Если ты проходил базовый курс, такой чертёж уже попадался тебе в Хранилище; если нет — ничего страшного, здесь мы разбираем его с нуля.

Открой чертёж зависшего отчёта:

EXPLAIN (читается «эксплейн», от англ. explain — «объясни») — команда, которая просит базу объяснить, КАК она собирается выполнять запрос. Пишется перед обычным запросом; сам запрос при этом не выполняется, поэтому команда безопасна и мгновенна даже на тяжёлом отчёте. В ответ приходит план — список шагов, которые машина проделала бы: что прочитать, чем соединить, что отсортировать.

Тот же запрос под EXPLAIN. Мгновенно: запрос НЕ выполнялся — машина показала только маршрут. Найди в дереве строку SubPlan и под ней Seq Scan on ls_readings: это и есть «пролистать журнал целиком», записанное языком машины. Строки JIT: в конце пока пропусти — так машина отмечает, что скомпилировала части дорогого запроса; к ним вернёмся, когда доберёмся до памяти и исполнителя.

Что ты сейчас увидел

Две вещи, которые важно забрать из этого чертежа уже сегодня:

  • Seq Scan on ls_readings — последовательное чтение журнала: все сто восемьдесят тысяч строк, строка за строкой. Само по себе это не преступление — иногда полный проход и правда дешевле всего.
  • SubPlan, который исполнитель запускает заново для каждой строки внешнего запроса. Полный проход × двести датчиков — вот арифметика зависшего отчёта.

Заметь, чего мы НЕ сделали: не создали ни одного индекса. Мы ещё не знаем, ли тут нужен, — может быть, запрос надо переписать, а может, и то и другое. Диагноз ставят по чертежу, а не по симптому.

КВЕРИ: Запомни сегодняшний порядок действий. Сначала — чертёж. Потом — выводы. Курсанты, которые делают наоборот, засевают архив индексами, как сорняками, — а отчёты всё равно ползут.

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

Check yourself
Отчёт стал медленным. Что делает инженер ПЕРВЫМ?