Воркфлоу детектива
O que você vai aprender
- складывать инструменты главы в один воркфлоу из пяти шагов
- находить узел, где горит время, — с учётом
loopsи времени детей - отличать « ослеп» от «маршрут честный, но дорогой»
- ставить полный диагноз отчёту из первого урока — и понимать, почему чинить его пока рано
Последняя вахта первой главы
Шесть ноль-ноль по станционному времени. Несколько вахт назад в этот самый час завис утренний отчёт — и КВЕРИ впервые открыл тебе люк на нижние палубы. С тех пор ты выучил язык чертежей: cost и rows, actual time и loops, страницы и Rows Removed, оценку против факта.
Сегодня новых инструментов не будет. Сегодня — порядок, в котором их достаёт инженер.
КВЕРИ: Любой курсант, тыкаясь наугад, с пятого раза найдёт в плане что-нибудь подозрительное. Инженер ищет всегда в одном и том же порядке — и поэтому находит с первого.

Пять шагов детектива
Когда запрос завис, инженер не «смотрит план» — инженер проходит по плану маршрутом, всегда одним и тем же.
Шаг 1. Сними полный чертёж: EXPLAIN (ANALYZE, BUFFERS). Один прогон — и все улики на руках: маршрут, реальное время, строки, страницы. Для SELECT это безопасно (про под ANALYZE ты помнишь ещё из Хранилища: он выполняется по-настоящему).
Шаг 2. Найди узел, где горит время. Не самый нижний и не самый страшный на вид, а узел с максимальным собственным временем: его actual time умножь на loops — приём из урока про хронометраж — и вычти время детей: время родителя всегда включает их время. Обычно девять десятых рейса сгорает в одном-двух узлах.
Шаг 3. Сверь оценку с фактом — est и actual — в этом узле. Est — то самое rows из первой скобки, прогноз штурмана; actual — факт из второй. Расхождение на порядок — ослеп: маршрут построен по неверным картам, и лечить надо карты, а не дорогу. Оценка сошлась — штурман всё видел и всё равно выбрал этот маршрут: дешевле по его модели не было, и думать надо о самой дороге.
Шаг 4. Посмотри, что прочитано зря: Rows Removed и Buffers. Сколько строк узел отбросил, едва прочитав, и сколько страниц поднял ради горстки нужных. Это перевод жалобы «медленно» на язык конкретных улик.
Шаг 5. Только теперь думай о починке. Индекс, переписанный запрос, обновлённые карты — лечение выбирают по диагнозу из шагов 2–4. Заметь, где стоит этот шаг: последним. Любая починка раньше этого шага — не починка, а гадание.
Дело №1: отчёт, который завис
Применим воркфлоу к делу, с которого началась глава. В первом уроке ты смотрел на этот запрос через простой — чертёж без рейса — и нашёл в дереве подозрительный SubPlan с полным проходом по журналу. Это было подозрение. Теперь собери доказательства.
Шаг первый — снять полный чертёж. Запусти и не удивляйся, что ячейка думает дольше обычного: на этот раз запрос выполняется по-настоящему, все двести прогонов по журналу.
SubPlan 1, а в нём Seq Scan on ls_readings: его loops, Rows Removed by Filter и Buffers — главные улики этого дела.Шаги 2–5: диагноз
Шаг 2 — где горит. Наверху — Index Scan по первичному ключу датчиков (так штурман отдаёт строки сразу в порядке ORDER BY, даже узел Sort не понадобился). Время у него огромное, но почти всё это — время его детей. А вот Seq Scan on ls_readings внутри SubPlan: несколько миллисекунд на прогон — мелочь, пока не умножишь на loops=200. Двести прогонов съедают почти весь рейс. Собственное время — максимальное в дереве: узел найден.
Шаг 3 — est против actual. В горящем узле оценка rows=450, факт — rows=539 в среднем на прогон. Расхождение даже не в полтора раза — никакого «на порядок». Планировщик не ослеп: карты свежие, маршрут по ним построен честно. Чинить статистику бессмысленно — маршрут дорог сам по себе.
Шаг 4 — что прочитано зря. Rows Removed by Filter: 179461 — каждый прогон отбрасывает сто семьдесят девять тысяч строк журнала ради ~539 нужных. И Buffers: shared hit=302600 — та самая пачка из 1513 страниц, которую ты считал в уроке про BUFFERS, прочитанная двести раз подряд. (Внизу плана появились строки JIT — на дорогих маршрутах машина на лету компилирует части плана; для нашего диагноза они не важны.)
Шаг 5 — починка? Диагноз готов: запрос двести раз перечитывает весь журнал, потому что коррелированный, а читать журнал точечно машине нечем. Лечений минимум два — переписать запрос так, чтобы журнал читался один раз, или дать штурману короткую дорогу к показаниям одного датчика. Оба ты освоишь в следующих главах — сегодня ни одного индекса мы так и не создали, и это правильно. У тебя впервые есть не жалоба «медленно», а дело с уликами.
У люка
Вы с КВЕРИ поднимаетесь с нижних палуб. Гул машины за спиной теперь звучит иначе — не шум, а речь, которую ты начал разбирать.
КВЕРИ: Хорошая вахта. Ты читал план, как читает инженер: по шагам, без гаданий. Знаешь, в журнале планов «Котомаркета» мне однажды попался странный , который… Неважно. Старая вкладка. Считай, что я дремал.
Он замолкает на полуслове и слишком быстро меняет тему; хвост его процесса на мгновение застывает. Ты не переспрашиваешь. Пока.
Отчёт всё ещё не починен — и это правильно: диагноз без лечения лучше, чем лечение без диагноза. Со следующей главы начинается само ремесло: какие вообще бывают маршруты по данным и почему штурман выбирает один, а не другой.