【问题标题】:Mongo compound array Index not being used未使用 Mongo 复合数组索引
【发布时间】:2015-10-09 11:03:02
【问题描述】:

我的数据库中有以下对象结构。

{
  "_id": 1234,
  "dateTime": ISODate("2015-09-28T02:15:00Z"),
  "tags":[{
     "_id": 5678,
     "name":{
       "short": "GOT",
       "long" : "Game of Thrones"
     }
   },{
     "_id": 9101,
     "name":{
       "short": "Dragons",
       "long" : "Huge Dragons"
     }
  }]
}

我正在尝试使用以下方式查询:

db.collection.find({ 日期时间:{ $gte:新日期(1443398000000),$lt:新日期(1443484740000)}, "tags._id": "d8408d19-48e4-36a0-aa23-55cd8c8415f6"}})

我创建了索引:

{ dateTime: 1, "tags._id": 1}

然而,当使用 explain() 运行查询时,它从不使用这个索引。

我曾尝试以相反的方式翻转索引并重新排序我的查询,但这没有帮助。

我的数据库中有大约 500,000 个文档。

希望有人可以提供帮助。

【问题讨论】:

  • 您能否在查询中包含.explain(true) 的输出?另外,您使用的是哪个特定版本的 MongoDB?

标签: mongodb indexing


【解决方案1】:

我就是这样查询的

> db.comp.find({dateTime:{"$gte":new Date(12345),"$lte":new Date(999999999)},"ta
gs._id":5678}).explain()

这是输出

{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "test.comp",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "$and" : [
                                {
                                        "tags._id" : {
                                                "$eq" : 5678
                                        }
                                },
                                {
                                        "dateTime" : {
                                                "$lte" : ISODate("1970-01-12T13:
46:39.999Z")
                                        }
                                },
                                {
                                        "dateTime" : {
                                                "$gte" : ISODate("1970-01-01T00:
00:12.345Z")
                                        }
                                }
                        ]
                },
                "winningPlan" : {
                        "stage" : "KEEP_MUTATIONS",
                        "inputStage" : {
                                "stage" : "FETCH",
                                "filter" : {
                                        "dateTime" : {
                                                "$gte" : ISODate("1970-01-01T00:
00:12.345Z")
                                        }
                                },
                                "inputStage" : {
                                        "stage" : "IXSCAN",
                                        "keyPattern" : {
                                                "dateTime" : 1,
                                                "tags._id" : 1
                                        },
                                        "indexName" : "dateTime_1_tags._id_1",
                                        "isMultiKey" : true,
                                        "direction" : "forward",
                                        "indexBounds" : {
                                                "dateTime" : [
                                                        "(true, new Date(9999999
99)]"
                                                ],
                                                "tags._id" : [
                                                        "[5678.0, 5678.0]"
                                                ]
                                        }
                                }

如果您看到 "indexName" : "dateTime_1_tags._id_1" 索引已被使用。

希望对你有帮助

【讨论】:

  • 它没有为我选择正确的查询,我得到了 dateTime 的单个索引边界。如果我提示使用正确的索引,性能真的很差,需要 70 秒才能返回
  • 我只是触发了相同的查询 db.comp.find({dateTime:{"$gte":new Date(1443398000000),"$lt":new Date(1443484740000)},"tags. _id":5678}).explain() 您在问题中提到并得到相同的结果。您是否发现此查询中有任何空白?
  • 不,你的查询看起来很好,你运行这个数据集有多大,尝试在 dateTime 字段中创建 500,000 个带有随机时间戳的文档,我自己也有一个 dateTime 索引,这个是它选择的那个
  • 您是否使用任何排序方式?
猜你喜欢
  • 2014-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-17
  • 1970-01-01
  • 2011-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多