【问题标题】:MongoDB find and iterate vs countMongoDB查找和迭代vs计数
【发布时间】:2018-11-29 23:07:59
【问题描述】:

我对 Mongo 有一个特殊的问题。

我们有一个包含 800k 文档的集合,其结构如下。

{
"_id" : ObjectId("5bd844199114bab3b2c19fab"),
"u" : 0,
"c" : 0,
"iden" : "343754856",
"name" : "alan",
"email" : "mkasd@abc.com",
"mobile" : "987654321093456",
"expires" : ISODate("2018-11-29T11:44:25.453Z"),
"created" : ISODate("2018-10-30T11:44:25.453Z")
}

我们已经索引了我们通常查询的idenname。 我们尝试了两种类型的查询。

  1. db.Collection.find({"iden": "343754856", "name": "alan", "created":
    {"$gt": ....}).count()

    其中“created”是一个未索引的字段。

  2. db.Collection.find({"iden": "343754856", "name": "alan"})

    并遍历所有记录以根据created进行过滤。

但是,MongoDB 似乎在执行第二个查询时花费了大量时间,而它应该是对 1 的优化。

关于这里出了什么问题的任何线索? 我们正在使用 Go 库。

【问题讨论】:

  • explain() 说什么?
  • 印度以外的人可能会对什么是“十万份文件”感到非常困惑,所以请不要在这里使用印度测量值。

标签: mongodb performance go


【解决方案1】:

第二个版本怎么可能比第一个更优化?

您的第一个查询从 MongoDB 服务器检索一个数字:查询结果的总计数。当您的第二个版本获取所有匹配的文档时,您在“客户端”端进行计数。

相信我,MongoDB 可以像在 Go 客户端中一样快速地在内部计算结果文档。让 MongoDB 服务器发送结果、获取它们并在客户端解组它们需要更多时间(取决于很多因素)。

请注意,如果您有一个包含"iden""name" 的复合索引,即使您添加了更多过滤器(如您的示例中的"created"),该索引仍可能被使用,但MongoDB 必须迭代在部分结果上应用查询的其余部分。要查看是否使用了索引,请执行以下命令:

db.Collection.find(
    {"iden": "343754856", "name": "alan", "created": {"$gt": ....}
).explain()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 2013-06-18
    • 2016-03-29
    • 2022-01-01
    相关资源
    最近更新 更多