我需要遍历约200万个文档的完整MongoDb集合。因此,我正在使用游标功能和eachAsync
函数。但是我注意到它非常慢(需要40多分钟)。我尝试了多达5000个不同的batchSizes(针对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函数体内设置一个断点时,它将立即命中。因此,没有任何卡住,它是如此之慢。有没有办法加快速度?
最佳答案
该功能是在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)
})
})