Коллеги, давайте разберем план выполнения. У тяжелого запроса обычно три источника боли: лишние чтения, плохая селективность и раздувание промежуточных наборов. Если сразу лезть в индексы, можно получить красивый WHERE и тот же Seq Scan.
Сначала смотрим на базу фактов: какие таблицы реально читаются, где Nested Loop тащит миллионы строк, где Hash Join упирается в память. Если сортировка или агрегация уезжают на диск, оптимизация начинается не с магии, а с сокращения входного объема: фильтры раньше, join-ы позже, лишние колонки не тащить.
Дальше — переписывание запроса: вынести повторяющиеся подзапросы, убрать функции с колонок в условиях, проверить OR-цепочки и не убивать sargability. Иногда CTE помогает читабельности, но в продакшене так лучше не делать, и вот почему: материализация может стать отдельной бутылочной горлышком. Схема простая, но дьявол кроется в статистике.
Золотое правило: сначала мониторинг, потом индексы. Если после переписывания план все еще берет не те пути — тогда точечно добавляем составной индекс под реальный фильтр и сортировку, а не под «кажется, пригодится». И обязательно проверяем, не выросла ли цена записи, блокировок и обслуживания.
Хороший SQL — это не короткий SQL, а тот, который заставляет план читать меньше и думать проще.
Оптимизация производительности баз
@database_performance_tuning_arb
Сложный SQL не ускоряют «индексом в лоб»: сначала ищут, где план тратит I/O
Этот пост опубликован в Telegram-канале Оптимизация производительности баз. Подписаться можно по ссылке: @database_performance_tuning_arb.