【问题标题】:MongoDB OR condition indexingMongoDB OR 条件索引
【发布时间】:2012-11-02 13:12:43
【问题描述】:

我有一个 OR 查询,目前用于半大型更新。基本上我的收藏分为两个数据集;

1 个主存储库和 1 个主存储库的子集。这只是为了更快地搜索一小部分数据。

我发现,我创建的用于将内容拉入子集的查询超时了。在查看说明时,看起来实际上正在发生两个查询。

PRIMARY> var date = new Date(2012,05,01);
PRIMARY> db.col.find(
  {"$or":[
      {"date":{"$gt":date}},
      {"keywords":{"$in":["Help","Support"]}}
   ]}).explain();

这会产生:

{
"clauses" : [
    {
        "cursor" : "BtreeCursor ldate_-1",
        "nscanned" : 1493872,
        "nscannedObjects" : 1493872,
        "n" : 1493872,
        "millis" : 1035194,
        "nYields" : 3396,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
            "ldate" : [
                [
                    ISODate("292278995-01--2147483647T07:12:56.808Z"),
                    ISODate("2012-06-01T07:00:00Z")
                ]
            ]
        }
    },
    {
        "cursor" : "BtreeCursor keywords_1 multi",
        "nscanned" : 88526,
        "nscannedObjects" : 88526,
        "n" : 2515,
        "millis" : 1071902,
        "nYields" : 56,
        "nChunkSkips" : 0,
        "isMultiKey" : false,
        "indexOnly" : false,
        "indexBounds" : {
            "keywords" : [
                [
                    "Help",
                    "Help"
                ],
                [
                    "Support",
                    "Support"
                ]
            ]
        }
    }
],
 "nscanned" : 1582398,
 "nscannedObjects" : 1582398,
 "n" : 1496387,
 "millis" : 1071902
}

有什么我可以更好地编制索引以加快速度吗?似乎只是慢下来...

提前谢谢!

【问题讨论】:

  • 你的索引是多少?只是提交日期?
  • 我尝试在关键字和日期上创建单独的索引;并尝试将它们创建为两者之间的复合索引。
  • 嗯,您正在那里获取 140 万条记录....数量不少,您可以尝试延长 mongo 游标上的计时器以进行如此大的查询。还有你在这里的设置是什么?我承认 17m 是很长的时间
  • @Sammaye 我正在尝试获取记录并获取所有符合条件的记录,然后将它们移动到仅包含实际字段子集的另一个集合中,从而创建一个可搜索的数据集。跨度>
  • 是的,您正在尝试聚合另一个集合,对吗?你是在客户端做的还是这个基于 MR 的?如果客户端基于什么语言(根据可能的驱动程序错误可能会有所不同)?

标签: mongodb indexing


【解决方案1】:

$or query 将分别评估每个子句并组合结果以删除重复项。因此,如果您想优化查询,您应该首先尝试分别explain() 每个子句。

问题的一部分似乎是您正在检索大量文档,同时积极写入该集合,正如高 nYields (3396) 所证明的那样。值得在查询运行时查看mongostat 输出以考虑其他因素,例如页面错误、锁定百分比和读/写队列。

如果您希望针对大量文档和非常活跃的集合更新加快查询速度,可以考虑以下两种最佳实践方法:

1) 预聚合

本质上,这是在插入/更新文档时更新聚合统计信息,以便您可以进行快速的实时查询。 MongoDB 手册更详细地描述了这个用例:Pre-Aggregated Reports

2) 增量映射/减少

incremental Map/Reduce 方法可用于计算连续批次的聚合统计信息(例如,来自每小时或每天的 cron 作业)。使用这种方法,您可以使用 reduce 输出选项执行 Map/Reduce 以将结果保存到新集合中,并包含一个 query 过滤器,该过滤器仅选择自上次此 Map/Reduce 作业以来已创建/更新的文档已运行。

【讨论】:

    【解决方案2】:

    我认为您应该在日期和关键字上创建一个复合索引。根据您的用例,请参阅下面的帖子了解更多详情

    how to structure a compound index in mongodb

    【讨论】:

    • 刚刚检查过;但是似乎 OR 条件仍在达到两个索引。认为这会使其变慢,因为它必须查看完全相同的索引两次,只使用一半的信息。
    • 一个 $or 可以使用两个索引计划并且会,它是 mongo 查询的一个特例。它从根本上源于 $or 在 Mongo 中是如何完成的
    • 复合索引没有帮助;正如 Sammaye 提到的 $or uses multiple indexes(每个子句一个)并结合结果以删除重复项。
    猜你喜欢
    • 2021-09-20
    • 2023-02-04
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多