Когда ты делаешь запрос на список сущностей, а для каждой из них внутри цикла идёт ещё один запрос — поздравляю, ты поймал N+1 проблему
Например:
const users = await db.query('SELECT * FROM users');
for (const user of users) {
user.posts = await db.query('SELECT * FROM posts WHERE user_id = $1', [user.id]);
}
Результат — один запрос на юзеров и N запросов на посты. На 100 юзеров это уже 101 запрос.
Больно для БД 😱😱😱
⚙️ Решения:
1) JOIN — часто помогает, если нужно просто склеить данные
2) IN-запрос — SELECT * FROM posts WHERE user_id IN (...)
3) DataLoader — если у тебя GraphQL или сложные вложенные запросы
🧠 Как работает DataLoader
DataLoader — это умный батчер и кэшер от Facebook
Он не делает магии, а просто:
1) Копит ключи (например, userId), по которым нужно загрузить данные
2) Выполняет один общий запрос, вроде:
SELECT * FROM posts WHERE user_id IN (1,2,3,...)
3) Раскладывает результат обратно по пользователям
Почитать подробнее можно тут
🚀 Пост Guru Node.js: @DemetraIT