На какие проблемы в плане выполнения запроса указывает EXPLAIN ANALYZE?

Ответ

EXPLAIN ANALYZE в PostgreSQL (и аналогичных СУБД) выполняет запрос и показывает реальный план выполнения с фактическим временем и количеством строк. Это мощный инструмент для поиска узких мест.

Основные "красные флаги", на которые стоит обратить внимание:

  1. Seq Scan (Последовательное сканирование) на больших таблицах. Главный признак отсутствия подходящего индекса для условия WHERE или JOIN. План с Index Scan почти всегда предпочтительнее.

  2. Большая разница между rows (оценка) и actual rows (факт). Если планировщик сильно ошибается в оценке количества строк (например, ожидает 10, а получает 1 000 000), он может выбрать неоптимальный способ соединения таблиц (JOIN). Обычно это говорит об устаревшей статистике. Решение: ANALYZE your_table;.

  3. Filter с большим количеством отброшенных строк. Если после сканирования по индексу (Index Scan) узел Filter отбрасывает большинство строк, значит, индекс не очень селективен (неэффективен) для данного запроса.

  4. Сортировки на диске (Sort Method: external merge Disk). Если для сортировки (ORDER BY) или некоторых видов JOIN не хватает памяти (work_mem), PostgreSQL сбрасывает временные данные на диск. Это крайне медленная операция, которую следует избегать, увеличивая work_mem или оптимизируя запрос.

  5. Высокое значение Planning time. Если планирование запроса занимает значительное время, это может указывать на его избыточную сложность, большое количество таблиц в JOIN или проблемы со статистикой.

  6. Nested Loop (Вложенные циклы) с большим количеством итераций. Этот метод соединения эффективен для малого количества строк во внешней таблице, но может стать катастрофически медленным, если планировщик ошибся с оценкой и итераций оказались миллионы.

Анализ EXPLAIN ANALYZE — это поиск самых "дорогих" (cost) и долгих (actual total time) узлов в плане и понимание, почему они стали узким местом.

Ответ 18+ 🔞

А, ну ты глянь, вот эта штука EXPLAIN ANALYZE в Постгресе — это ж, блядь, как рентген для твоего кривого запроса. Запускаешь, а он тебе не просто план нарисует, а реально выполнит всё и вывалит, где и сколько секунд твоя программа просидела на унитазе, размышляя о жизни.

Смотри, вот на что глаза пялить, чтобы не охуеть от результата:

  1. Seq Scan на таблице, которая больше, чем твои амбиции. Это главный крик души базы: «Чувак, где, блядь, индекс?!». Если видишь эту хрень на большой таблице — значит, запрос тупо читает её всю, от корки до корки. Нужен Index Scan, ёпта!

  2. Цифры в rows и actual rows различаются, как небо и земля. Планировщик думал, что строк будет 100, а их оказалось 100 000. Ну и как он, мудя, выберет нормальный план? Он ж ожидал лёгкой прогулки, а получил марш-бросок. Чаще всего статистика постарела. Лечится командой ANALYZE your_table;, чтобы база заново всё пощупала.

  3. Узел Filter отбрасывает почти всё, что нашёл. Представь: индекс тебя привёл в нужный район города (Index Scan), а потом ты (Filter) ходишь и стучишь в каждую дверь, чтобы найти одну квартиру. Индекс — говно, не селективный. Ищем другой или переписываем запрос.

  4. Сортировка ушла на диск: Sort Method: external merge Disk. Это пиздец, а не красный флаг. Это когда твоему запросу не хватило оперативки (work_mem), и он начал сраные промежуточные данные на жесткий диск скидывать. Скорость падает ниже плинтуса. Либо память (work_mem) добавляй, либо запрос так переделывай, чтобы меньше данных сортировать.

  5. Planning time — огромный. Это сколько времени база мозги ломала, как выполнять запрос. Если это время сопоставимо с самим выполнением — у тебя или запрос слишком хитрожопый, или статистика опять всё проебала.

  6. Nested Loop с миллионом итераций. Сам по себе способ нормальный, для маленьких наборов данных. Но если планировщик обосрался с оценкой и думал, что внешняя таблица — это 10 строк, а там миллион... Ну, представляешь? Миллион раз выполнить внутренний цикл. Ебать ты лопнешь, пока запрос выполнится.

Короче, суть в чём: Запустил EXPLAIN ANALYZE, нашёл в выводе самые жирные цифры в actual total time и cost. Вот эти узлы и есть твои узкие места, твоя «хитрая жопа», которая всё тормозит. Разбирайся, почему они такие медленные — обычно всё сводится к индексам, статистике или кривой логике запроса.