聚合阶段的MongoDB [索引优化]性能

时间:2018-11-06 09:28:35

标签: javascript mongodb performance optimization mongoose

我的Mongo数据库中有大约50 M 个文档,名为dma,我使用这种汇总来获取必要的数据res,然后对其进行处理。

async function FormContract(ownerRealm, id) {
    try {
        const res = await collection.aggregate([
        {
            $match: {
                date: {$gt:moment.utc().subtract(1, 'days').toDate(), $lt:moment.utc().toDate()},
                id: id, //45 values one by one
                ownerRealm: {$in: ownerRealm} //20 values one-by-one
            }
        },
        {
            $group: {
                _id: "$lastModified",
                open_interest: {$sum: "$buyout"},
                min: {$min: "$price"},
                min_size: {$min: {$cond: [{$gte: ["$quantity", 200]}, "$price", "$min:$price"]}},
                avg: {$avg: "$price"},
                max: {$max: "$price"},
                max_size: {$max: {$cond: [{$gte: ["$quantity", 200]}, "$price", "$max:$price"]}},
                stdDevPop: {$stdDevPop: "$price"},
                cp: {$addToSet: "$owner"},
            }
        }]).exec();...

我的收藏的模式如下:

auc: { type: String },
id: { type: Number },
owner: { type: String },
ownerRealm: { type: String }, //20 unique values
bid: { type: Number },
buyout: { type: Number },
price: { type: Number },
quantity: { type: Number},
timeLeft: { type: String },
lastModified: { type: Number }, 
date: { type: Date, required: true } 

就目前而言,关于我的问题有两句话。 我有约15个 M 个文档,其中涉及$match查询date: {$gt:moment.utc().subtract(1, 'days').toDate(), $lt:moment.utc().toDate()},

可以肯定的是,我只需要最新的文档,因此显然它们将被插入收藏集的末尾

然后,我需要在其后进行20个(域)x 45个(id)aggregation个查询。我的功能可以正常运行,但最终可以执行。

记住,我并不是说它很慢!

用例:

  • 如果我在for (ownerRealms.length)内使用for(id.length)

    for (let i = 0; i < ownerRealms.length; i++) {
        for (let j = 0; j < id.length; j++) {
            FormContract(ownerRealm, id)
    

    20 servers x 45 id = 900查询将形成必要的数据 每次大约20分钟内CPU和RAM上没有高负载 服务器,或20 mins x 20 servers = 400 mins 或〜6 HOURS!

  • 或者如果我使用for(id.length)map(servers)

    for (let j = 0; j < id.length; j++) {
        const data = await Promise.all(ownerRealms.map(async ({ ... }) => {
             FormContract(ownerRealm, id)
    

    那将是异步的 20 $aggregation一对一查询45次。或每10个ID 1小时 或〜4.5 Hr(好得多了吗?),但是它会在 CPU(利用率几乎为90%的几乎所有内核,有问题)

我使用7核,7Gb RAM和80'000 + IOPS SSD的机器,因此如果我接受4.5小时的90%CPU负载,我想我做错了

那么,有什么想法对优化会更好吗?首先,我在此集合中创建索引,它看起来像这样:

lastModified:-1
ownerRealm:1
date:-1
id:-1

但是根据Mongo Compass的说法,它有0种用法,并存储在名为undefinded的单独的DB集合中。图片在这里:

enter image description here

那是什么问题?我做错了吗?我应该创建一个更好的索引。还是我错过了另一种方法,例如在$match阶段在其他地方存储数据?还是使用$sort阶段?我已经读过$match查询应该放在第一位,因为它调用了所有集合。

我已经检查了以下 StOv 问题:Index optimization for mongodb aggregation frameworkIncrease MongoDB performance with sort,并且已经检查了dba.stackexchange有用的内容。

0 个答案:

没有答案