dd

600 запросов вместо одного

Написано

в

Сколько по-вашему нужно сделать запросов в базу для получения данных для списка (некоторые поля основной сущности + данные из смежных сущностей, где-то с агрегациями) с учетом фильтров?
10? 20? 50? Как насчет 600?)
Именно так и "работало" апи одного из сервисов на подработке
Сначала тянулись все отфильтрованные сущности, потом по каждой сущности отдельно собирался набор данных из кучи методов, в каждом по 1-2 запроса в базу
Работало это все ваще прекрасно: выгрузка из 50 сущностей занимала 7 секунд и делала те самые 600 запросов
Индексов на таблицах было ровно 0)

В целом, наверное, можно было бы забить на это. Да, грязно, криво и работает медленно, но ведь работает же. Большинству людей, которые этим фильтром пользуются, вообще до лампочки — 7 секунд оно выполняется или 0.5, это все-таки не диспетчерская МЧС.
Но есть и меньшинство, которому очень надо делать выгрузку этих отфильтрованных списков в эксель. А это уже совсем другая песня. Вот тут нас и поджидала жопа
Оказывается, иногда выгрузить нужно вообще все строки таблицы (+- 3к). Зачем и почему — опустим, нам не за это деньги платят
Факт в том, что выгрузка в эксель полностью основывается на фильтре. Это удобно и позволяет избежать ненужного дублирования кода
Теперь вспоминаем, что 50 сущностей выгружается за 7 секунд, значит 3000 выгрузится за сколько? Неправильно, не за 420, потому что время выполнения выгрузки растет совсем не линейно

Варианты решения были космические! Давайте прикрутим центрифугу и кролика, чтобы в фоне задачи выполнять и отправлять результат на клиент! Давайте сделаем отдельную страницу с выгрузками, чтобы за ними можно было следить в реалтайме!
Угадайте какой из вариантов был мой 😀
Задача из-за обсуждений лежала спокойно в беклоге, а однажды я просто сидел пил кофе и на меня снизошло откровение — а с какого хрена вообще выгрузка такого малого количества записей занимает так много времени?

Из этого получился максимально простой выход — выполнять как можно больше работы за 1 запрос, тем самым максимально снижая время общения с базой. Сам по себе в приложении код очень простой, там экономить нечего
Но тут я немного схитрил: если сейчас запросов 600, то сильно будет разница, если их станет 1 или 2? Я по итогу разделил процесс выгрузки на 2 этапа: поиск идентификаторов сущностей с учетом фильтров и собственно сам сбор данных, используя найденные идентификаторы. Примерно как ведется работа с эластиком

Сам запрос на сбор данных это простецкий селект с под-селектами, в том числе с агрегацией в json-объекты
Если вы из тех людей, которые до сих пор считают, что под-селекты и джсон в постгре это медленно и тупо, то … может быть вы и правы, но в данном случае это не имеет значения, тут все-таки не хайлоад

По итогу получаем очень даже хороший прирост. Выгрузка 50 сущностей стала занимать 0.9-1с, а экспорт в эксель 700 записей около 2 секунд
Да, не горы свернули, но базе и пользователям жизнь облегчили)

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *