2016-11-21 1 views
2

Допустим, у меня есть скрипт, который обрабатывает N пользователей. Скрипт может выглядеть одним из двух способов, который быстрее предполагает наличие достаточных ресурсов? Я мог бы использовать либо Promise.all, либо async.parallel.Масштабирование в Node.js с помощью MongoDB, когда я должен запрашивать все идентификаторы сразу, а также параллельно запрашивать каждый из них?

Вариант 1

function processUsers(userIds) { 
    monog.find({_id: { $in: userIds }, (userDocs) => { 
     const tasks = userDocs.map((userDoc) => processUser(userDoc)) 
     async.parallel(tasks, (err, results) => console.log('finished')) 
    }); 
} 

Вариант 2

function processUsers(userIds) { 
    const tasks = userIds.map((userId) => { 
     mongo.findOne({_id: userId}, (err, userDoc) => { 
      processUser(userDoc); 
     }) 
    }) 
    async.parallel(tasks, (err, results) => console.log('finished')) 
} 
+1

В варианте 2 вы выполняете целую цепочку больше запросов db, что займет много больше времени, чем один запрос. Это вопрос с подвохом? :-) –

ответ

0

Самый лучший вариант, чтобы прочитать все в один раз или, по крайней мере, читать их в большие куски. Определенно не читайте их один за другим, это будет много ненужного трафика db. Прочитайте все сразу, если вы считаете, что у вас достаточно памяти для этого.

Кроме того, случайная мысль, но если processUser включает в себя записи DB, вы можете собирать результаты и использовать bulkWrite, чтобы ускорить работу даже больше.

0

Вариант 1 кажется лучшим выбором ИМО. find() работает лучше, чем findOne(), так как при использовании find() вы возвращаете курсор, а не фактические данные из базы данных. Перемещение этого курсора даст лучшие результаты, чем получение каждого документа по отдельности с помощью findOne().

0

Я бы сказал, это зависит.

Эти две операции: запрос (find/findOne) и обработка данных (processUser()) - в зависимости от того, какой из них больше работает на виртуальной машине, вы можете заставить их использовать асинхронное поведение Node.js. Например, если find() находится в порядках миллисезонов, где обработка выполняется в секундах, вы должны сделать процесс асинхронным, так как вы не хотите их упорядочивать, чтобы добавить общее время.

В общем случае запрос db связан с привязкой ввода/вывода и занимает больше времени, чем операции с привязкой к памяти, мы должны действительно видеть специфику рабочей нагрузки и соответственно принимать вызов.

Надеюсь, это поможет.