Я использую pg-обещание в приложении GraphQL, и из-за вложенного/итеративного характера распознавателей каждый HTTP-запрос делает много запросов к базе данных.
Итак, мне интересно, есть ли более эффективный способ поделиться соединением из пула соединений, когда распознаватели собирают данные?
Я понимаю, что задача pg-promise актуальна только для обратного вызова функции, и я не вижу другого способа связать запросы (как задокументировано здесь).
Запрос GraphQL:
{
users {
files {
name
date
}
}
}
Пример распознавателей при использовании Сервер Аполлона
Query: {
users: (obj, args, context, info) => {
return context.db.manyOrNone('select id from users')
}
}
и
Users: {
files: (obj, args, context, info) => {
const userId = obj.id;
return context.db.manyOrNone('select * from files where user_id = $1', userId);
}
}
Это создаст множество SQL-запросов, если, например, много пользователей.
ПРИМЕЧАНИЕ
Я знаю о таких методах, как dataloader, для решения таких проблем, как выбор N+1, но я не могу позволить себе изменить архитектуру этого приложения в данный момент, и просто более эффективное подключение к базе данных было бы огромным выигрышем в производительности.
Спасибо.





Каждая конечная точка HTTP и каждое соединение с базой данных из пула должны быть асинхронными.
Если вы попытаетесь повторно использовать одно и то же соединение с базой данных на нескольких конечных точках HTTP, они будут блокировать друг друга всякий раз, когда им потребуется доступ к базе данных, что нехорошо.
И если количество подключений в пуле меньше, чем количество конечных точек HTTP, которые обращаются к базе данных, вы получаете плохо масштабируемый HTTP-сервис. Вам нужно количество подключений, по крайней мере, чтобы соответствовать количеству конечных точек HTTP.
Итак, что вы ищете - совместное использование соединения с базой данных несколькими конечными точками HTTP - плохая идея для начала.
А если вы хотите сгруппировать несколько распознавателей данных в рамках одного HTTP-запроса, вы можете унифицировать логику обработки в рамках одной задачи (см. Задания).
Существует также ручное подключение с помощью метода соединять, но я бы не рекомендовал его для общего повторного использования подключения, так как он существует для конкретных случаев, в противном случае может быть подвержен ошибкам и сводит на нет идею автоматических подключений.
Я считаю, что проблема, скорее всего, в том, что вы неправильно подходите к задаче. Лучше всего выяснить, как это сделать, поскольку это, по сути, тот же контекст. В этом случае использование метода connect было бы обходом недостатка реализации.
Да, это то, что я понял. Круто, спасибо за проверку на вменяемость. Сначала я попробую использовать connect и посмотрю, какова производительность, пока ищу долгосрочное решение с использованием задач.
Спасибо @vitaly-t, мой вопрос больше относится к совместному использованию соединения для множества вызовов БД в пределах одним запросом, не обязательно между конечными точками (думал, что это запутывается с graphql). По сути, я спрашиваю, есть ли способ использовать метод Task, но это не ограничивается обратным вызовом, с которым он вызывается. Я не могу поместить эту часть кода в этот обратный вызов. Имеет ли это смысл?