Запрос работал 40 секунд. Исправили одной строкой. Стало 0,06 мс. 🚀
Недавно разбирали интересный кейс у клиента.
Сначала прилетели алерты. Один запрос выполнялся 37 секунд, потом 39, а потом уже больше 40. Параллельно начали писать пользователи, что сайт иногда подвисает.
Первая мысль - где-то тяжелый SQL или кто-то накосячил с логикой.
Оказалось, вообще нет.
Запрос самый обычный.
Начали копать глубже и нашли проблему совсем в другом месте.
Запрос искал записи, которые еще не обработаны. Но почти все записи в таблице уже были обработаны.
В итоге PostgreSQL каждый раз проходил по 1,3 миллиона строк, чтобы найти буквально несколько нужных.
Из-за этого запрос, который обычно должен работать за доли миллисекунды, иногда висел по 40 секунд. 🤯
Исправление заняло одну строку.
Добавили частичный индекс только для тех записей, которые реально участвуют в запросе.
Все.
Без переписывания приложения.
Без нового сервера.
Без рефакторинга.
В итоге получилось вот так:
✅ Было - 40 секунд. ✅ Стало - 0,06 мс.
Люблю такие истории.
Потому что в очередной раз убеждаешься: проблема производительности очень часто не в архитектуре, не в железе и не в PostgreSQL.
Она в одной маленькой детали, на которую никто не посмотрел.
В Telegram разобрал этот кейс полностью: показал планы выполнения до и после, объяснил, почему обычный индекс здесь не сработал, и рассказал, как создавать такие частичные индексы на проде без остановки сервиса.
Если у вас тоже иногда бывают запросы, которые вчера летали, а сегодня вдруг начинают тормозить без видимой причины, советую посмотреть этот разбор. Возможно, сэкономите себе несколько часов дебага.
Ссылка на Telegram (в профиле)💡
В этом посте были ссылки, но мы их удалили по правилам Сетки