Я являюсь автором pg-promise.
Ниже приведено несколько соображений о недопустимом использовании Promise.all
в этом контексте в ответе, который теперь удален.
При использовании интерфейса на основе обещаний, представляющего физические ресурсы, важно понять используемый физический контекст. Без этого вы рискуете столкнуться с узкими местами из простого факта, что физические ресурсы не масштабируются, как ваши общие обещания.
В случае pg-promise
ваших физического контекста состоит из двух вещей:
- строки запроса будет конвейер через Node.js IO
- контекста соединения предоставленного пулом соединений
Каждый запрос запроса получает и освобождает соединение из пула соединений, который является очень ограниченным физическим ресурсом. Размер вашего пула по умолчанию равен 10, как установлено базовым драйвером node-postgres
. И хотя вы можете увеличить его до 100, это приведет к созданию перегрузки в управлении соединениями, поэтому он не масштабируется. Типичное увеличение должно быть установлено на 20, что примерно равно среднему значению.
Итак, если вы используете Promise.all
в своем массиве запросов, ваше приложение будет истощать пул почти мгновенно, и любой следующий запрос в вашу службу будет просто сидеть там, ожидая доступных подключений.
Такое решение не может масштабироваться вообще, и оно указано как анти-шаблон для выполнения запроса здесь: Tasks versus root/direct queries.
В принципе, то, что он объясняет там необходимо выполнить несколько запросов через задачи:
- Метод task, если вы не изменяете данные
- Метод tx (транзакций), если вы меняете данные
Таким образом, вы можете передавать все ваши запросы через одно соединение, что необходимо для обеспечения масштабируемости вашего сервиса.
Там множество примеров в Learn By Example учебник как для Tasks и Transactions.
А учитывая, что вы пытаетесь получить Mutiple родительские строки, а затем несколько дочерних строк, вы должны смотреть на этот вопрос: get JOIN table as array of results with PostgreSQL/NodeJS.
Я также предлагаю прочитать статью Performance Boost, чтобы лучше понять физические ограничения выполнения нескольких запросов и способы их решения.
Пример
function getTeamMembers(aTeam) {
return db.task(t=> {
return t.map('SELECT * FROM team_members WHERE id=$1', aTeam.id, tm=> {
return t.any('SELECT * FROM users WHERE name=$1', tm.username)
.then(users=> {
tm.users = users;
return tm;
});
}).then(t.batch);
});
}
// usage example:
getTeamMembers({id: 123})
.then(members=> {
// members = array of member objects
})
.catch(error=> {
// error
});
Это не единственный способ сделать это, но это самый короткий;)
Этот подход дается лучше рассмотреть в следующий вопрос: get JOIN table as array of results with PostgreSQL/NodeJS.
Интересно, кто это сделал. Но, может быть, вы должны добавить код? – Bergi
@ Bergi, да, я отвечал в спешке, с работы, подробно расскажу, когда получится шанс. Был также наткнулся на критику со стороны автора первого ответа (теперь он удален). Думаю, это просто плохой день. –
Hi Vitaly - вы могли бы предоставить некоторый код в качестве примера? Я бы хотел это увидеть! Я рассмотрю ваши предложения, спасибо за помощь в повышении моих знаний и кода! –