迭代MongoDB游标很慢

时间:2017-10-10 16:13:22

标签: javascript node.js mongodb mongoose

我需要用大约200万个文档迭代一个完整的MongoDb集合。因此我使用光标功能和eachAsync功能。但是我注意到它很慢(需要40多分钟)。我尝试了不同的batchSizes到5000(这对MongoDB只有400次查询)。

应用程序不占用大量CPU(0.2% - 1%),也不占用大量RAM或IOP。显然我的代码可以进行优化,以加快这个过程。

代码:

  const playerProfileCursor = PlayerProfile.find({}, { tag: 1 }).cursor({ batchSize: 5000 })
  const p2 = new Promise<Array<string>>((resolve, reject) => {
    const playerTags:Array<string> = []
    playerProfileCursor.eachAsync((playerProfile) => {
      playerTags.push(playerProfile.tag)
    }).then(() => {
      resolve(playerTags)
    }).catch((err) => {
      reject(err)
    })
  })

当我在eachAsync函数体内设置断点时,它会立即命中。所以没有任何问题,它只是如此缓慢。有没有办法加快速度呢?

1 个答案:

答案 0 :(得分:4)

该版本已在4.12版本中添加(最新版本为atm),尚未真正记录。

默认情况下,

eachAsync以并发为1运行,但您可以在参数“parallel”中更改它。 (as seen here

因此,您的代码可能如下所示:

const playerProfileCursor = PlayerProfile.find({}, { tag: 1 }).cursor({ batchSize: 5000 })
const p2 = new Promise<Array<string>>((resolve, reject) => {
const playerTags:Array<string> = []
playerProfileCursor.eachAsync((playerProfile) => {
  playerTags.push(playerProfile.tag)
}, { parallel: 50 }).then(() => {
  resolve(playerTags)
}).catch((err) => {
  reject(err)
})
})