adelkhalitov
@adelkhalitov
>

Как ускорить работу метода в js или как сделать массовое обращение к бд?

Вопрос очень простой. Есть метод, который выполняет простую задачу. К примеру.
Есть товар который хранится в таблице good, есть остатки товаров хранятся в таблице balances, есть еще 200 необходимых параметров который относятся к товару.

Пример реализации

async some(id) {
let good = await goods.findOne(id);
let balance = await balances.findOne(some);
.... итп так 200 раз
}

Выполнение этой функции займет примерно 300 дней, условно. Вариант не подходит тк долго

Видел реализацию такую
let goodsObj = {};
let promises = [goods.findOne(id, goodsObj), balances.findOne(some, goodsObj) ...200 обращений в бд];
Promise.all(promises);

Скорост быстрее, нагрузка на базу хорошечная, в данном случае каждый метод в массиве promises просто добавляет новый ключ с каким то значением в объект goodsObj.

Вариант имеет место быть, но я пытался отладить подобный проект на 6 сервисов в такой реализации, после этого в своем паспорте гражданина РФ ручкой написал, что так никогда реализовывать не буду.

Я уверен что есть 3й вариант, самый правельный как это реализовать.
БД совершенно любая монга, мускул итп. Дайте пж направление
  • Вопрос задан
  • 217 просмотров
Решения вопроса 1
@Romaboy
Метод Promise.all не только лишь ждет, а и возвращает результаты, по этому объект не нужен:
const [a, b] = await Promise.all([query1, query2])
Если их реально 200, то объект конечно лучше будет) В жизни такого не видел, 10+ запросов на странице - уже тянет отрефакторить, да разные бывают кейсы, это наверняка очень необычная задача.

Дальше относится к postgres, монгу не знаю:

Чтобы не оптимизировать ни базу, ни сами запросы можно использовать пул соединений.
Одно соединение с базой (один сокет) может одновременно ожидать только один ответ, то есть от промисов толку будет ровно 0.

К базе можно одновременно послать множество запросов через одно соединение:
SELECT 1; SELECT 2; SELECT 3
Базы понимают точку с запятой, умеют распараллеливать, но вот беда! Скорее всего js библиотека так не умеет. Окей, на самом деле не уверен что это параллельно выполнятся, но базы точно умеют на такой соединенный запрос отвечать и это быстрее работало бы чем 3 отдельных.

Ещё postgres умеет превращать строку в json и можно писать что-то вроде
SELECT
  (SELECT row_to_json(table.*) FROM table LIMIT 1) AS one_result,
  (SELECT json_agg(row_to_json(table.*)) FROM table LIMIT 1) AS second_result

Такая конструкция в one_result вернет json одной записи, в second_result массив, эти два запроса никак не связаны между собой, выполняются в одном обращении, база у себя из распараллеливает, все круто и здорово, но для разработчиков это слишком сложно и я нигде почти такого не видел, когда писал - ловил косые взгляды, библиотеки сами такое генерировать не умеют. (как раз пишу одну чтобы умела, осталось самое сложное - дока)

В монге аналог join называется lookup, goods.findOne(id) похоже на монгу
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы