首页 > 解决方案 > node.js 的 MongoDB 驱动程序性能缓慢

问题描述

我有一个缓慢的数据获取问题。我有以下查询来获取数据

const query1 = this._ctx.signals.find({
    user_id: user._id,
    'spell.id': null,
    'metadata.0.spell_id': { $in: spellsIds }
}).hint({user_id: 1, 'spell.id': 1, 'metadata.0.spell_id': 1}).explain('allPlansExecution')

根据解释的执行时间是35ms。这是解释对象

{
queryPlanner: {
    plannerVersion: 1,
    namespace: 'gringotts.Signals',
    indexFilterSet: false,
    parsedQuery: { ... },
    winningPlan: {
        stage: 'FETCH',
        inputStage: {
            stage: 'IXSCAN',
            keyPattern: {
                user_id: 1,
                'spell.id': 1
            },
            indexName: 'user_id_1_spell.id_1',
            isMultiKey: false,
            multiKeyPaths: {
                user_id: [],
                'spell.id': []
            },
            isUnique: false,
            isSparse: false,
            isPartial: false,
            indexVersion: 2,
            direction: 'forward',
            indexBounds: { ... }
        }
    },
    rejectedPlans: []
},
executionStats: {
    executionSuccess: true,
    nReturned: 23866,
    executionTimeMillis: 35,
    totalKeysExamined: 23869,
    totalDocsExamined: 23866,
    executionStages: {
        stage: 'FETCH',
        nReturned: 23866,
        executionTimeMillisEstimate: 1,
        works: 23869,
        advanced: 23866,
        needTime: 2,
        needYield: 0,
        saveState: 23,
        restoreState: 23,
        isEOF: 1,
        docsExamined: 23866,
        alreadyHasObj: 0,
        inputStage: {
            stage: 'IXSCAN',
            nReturned: 23866,
            executionTimeMillisEstimate: 1,
            works: 23869,
            advanced: 23866,
            needTime: 2,
            needYield: 0,
            saveState: 23,
            restoreState: 23,
            isEOF: 1,
            keyPattern: {
                user_id: 1,
                'spell.id': 1
            },
            indexName: 'user_id_1_spell.id_1',
            isMultiKey: false,
            multiKeyPaths: {
                user_id: [],
                'spell.id': []
            },
            isUnique: false,
            isSparse: false,
            isPartial: false,
            indexVersion: 2,
            direction: 'forward',
            indexBounds: { ... },
            keysExamined: 23869,
            seeks: 3,
            dupsTested: 0,
            dupsDropped: 0
        }
    },
    allPlansExecution: []
},
serverInfo: {
    host: 'ip-192-168-1-98.ec2.internal',
    port: 27017,
    version: '4.4.4',
    gitVersion: '8db30a63db1a9d84bdcad0c83369623f708e0397'
},
ok: 1

}

当我尝试使用以下代码获取数据时,我的执行时间从 750 毫秒到 900 毫秒(21 倍)。平均文档大小为 544.6135124888154 字节。

console.time('q1-time')

const q1 = await this._ctx.signals.find({
    user_id: user._id,
    'spell.id': {
        $in: spellsIds
    }
    // @ts-ignore
}).hint({
    user_id: 1,
    'spell.id': 1
})

const f = (q) => {
    const result = []

    return new Promise((res, rej) => {
        q.stream().on('end', function() {
            console.log('done processing stream')

            res(result)
        })

        q.stream().on('data', (d) => {
            result.push(d)
        })
    })
}

const data = await f(q1)

console.timeEnd('q1-time') -- > q1 - time 769.511 ms

我尝试了不同的方法:.toArray,通过光标迭代和带有流的迭代(我在上面发布)是最快的)。

为什么获取数据需要这么长时间?它可以以某种方式优化吗?

标签: node.jsmongodbperformance

解决方案


推荐阅读