【问题标题】:Mongo Db optimized queryMongodb优化查询
【发布时间】:2015-01-21 20:47:10
【问题描述】:

在我的用例中,我有超过 3000 个变量 id,我已将它们分配给其他集合作为 mongo db 中的外键。在另一个集合中,对于每个外键,有更多数量的文档包含列表类型中的一个字段。我需要通过满足每个外键列表的至少一个文档的大小大于0的条件来查询从3000中检索不同的外键。我目前正在使用以下查询作为示例。

db.values.distinct('variable',{variable:{$in:variableIds}, $nor:[{source: {$exists: false}},{source: {$size: 0}}]})

其中变量是“值”集合的外键,如下所示。 variableIds 是变量集合中作为主键的唯一 id 列表。

{
"_id" : ObjectId("546db048e4b0c0187ab9eefd"),
"dateNum" : 41274,
"source" : [
    {
        "value" : 625,
        "formatCode" : "General"
    }
],
 "variable"  : ObjectId("546db048e4b0c0187ab9eefc")
}

但由于$in 条件中有 3000 个 id,查询似乎很大并且需要更多时间来执行,是否有其他方法可以优化查询?

【问题讨论】:

    标签: mongodb query-optimization


    【解决方案1】:

    一种优化是将variable 字段添加到index

    只是为了展示它的效果。让 values 是一个只有三个文档的集合,其中两个与我们正在寻找的 variable 匹配。

    样本数据:

    db.values.insert([{
    "_id" : 1,
    "dateNum" : 41274,
    "source" : [
        {
            "value" : 625,
            "formatCode" : "General"
        }
    ],
     "variable"  : 1
    },
    {
    "_id" : 2,
    "dateNum" : 41274,
    "source" : [
        {
            "value" : 625,
            "formatCode" : "General"
        }
    ],
     "variable"  : 1
    },
    {
    "_id" : 3,
    "dateNum" : 41274,
    "source" : [
        {
            "value" : 625,
            "formatCode" : "General"
        }
    ],
     "variable"  : 2
    }
    ])
    

    假设我们在没有变量字段索引的情况下对该集合运行查询。

    db.runCommand({ distinct: 'sample',
                    key:'variable',
                    query:{variable:{$in:[1]}, 
                           $nor:[{source: {$exists: false}},{source: {$size: 0}}]}
                  })
    

    我们得到以下输出。在检查输出时,我们发现集合中扫描的文档总数的值 - nscannedObjects3。所以这导致了完整的集合扫描。

    {
            "values" : [
                    1
            ],
            "stats" : {
                    "n" : 2,
                    "nscanned" : 3,
                    "nscannedObjects" : 3,
                    "timems" : 0,
                    "cursor" : "BasicCursor"
            },
            "ok" : 1
    }
    

    现在我们在variable 字段上添加一个索引。

    db.sample.ensureIndex({"variable":1})
    

    在运行命令时,我们得到以下输出,表明扫描的文档总数仅为2。这些文档与搜索查询中的 variable 完全相同。

    {
            "values" : [
                    1
            ],
            "stats" : {
                    "n" : 2,
                    "nscanned" : 2,
                    "nscannedObjects" : 2,
                    "timems" : 59,
                    "cursor" : "BtreeCursor variable_1"
            },
            "ok" : 1
    }
    

    【讨论】:

    • 我添加了索引也显示了相同的结果,并且我还搜索在 $in 中传递超过 3000 个项目会导致任何性能问题,并且除了使用 distinct 之外还有其他替代查询跨度>
    • 索引字段variablesource.value。然后尝试以下查询: db.sample.distinct('variable',{variable:{$in:[1]}, "source.value":{$exists:true}})
    猜你喜欢
    • 2015-01-09
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    • 2021-09-03
    • 2019-10-25
    • 2020-07-05
    相关资源
    最近更新 更多