Когда JOIN тянет ко дну: как одно изменение ускорило запрос в 75 раз

В статье на примере тестового стенда PostgreSQL показывается, как замена тяжёлого многотабличного JOIN на коррелированный подзапрос и использование индексов позволяют ускорить SQL-запрос в 75 раз. Классическая задача — для каждого пользователя рассчитать несколько агрегатов из связанных таблиц: среднее и максимум по разным данным. Изначальный запрос строился на нескольких JOIN, из-за чего происходило перемножение строк (30 × 500 × 20 на пользователя, итого 150 млн строк), глобальная сортировка и лишний параллелизм, что приводило к времени выполнения около 48 секунд.

Оптимизация заключалась в замене самого тяжёлого JOIN (для max из table2.value) на подзапрос с агрегацией и опорой на индекс. Новый план вместо каскадного перемножения строк позволяет СУБД быстро находить максимум по user_id через Bitmap Index Scan, сократить поток данных до 600 тыс. строк и обойтись без глобальной сортировки. Итоговое время выполнения уменьшилось до 0,64 сек — в 75 раз быстрее оригинала. Статья подчёркивает ценность ранней агрегации, грамотного использования индексов и подзапросов вместо «монструозных» JOIN.

  • Исходный план: 150 млн строк, 47,9 сек выполнения
  • Оптимизированный план: 600 тыс. строк, 0,64 сек
  • Ключевые приёмы: коррелированные подзапросы, Bitmap Index Scan, минимизация параллелизма и сортировок

Рекомендации — не тащить большие агрегаты через JOIN, а выделять их в отдельные подзапросы с индексом. Подробности и кейсы — в канале автора.

← Назад в лентуЧитать оригинал →
✈️ Подписывайтесь на мой Telegram-канал — там еще больше интересного про AdTech, MarTech, AI и многое другое!