【发布时间】:2021-05-05 04:20:10
【问题描述】:
mongodb 经常使用索引,在过滤器中包含字段 no,该字段将使用 [MaxKey , MinKey] ,这与我在索引前缀文档中看到的不一样。
这样的查询:
db.Wager.aggregate([
{"$match":
{
"CompanyId": 1341,
"UpdatedDateUtc" : {"$gte" : ISODate("2021-03-25T23:35:00Z")}
}},
{$project:
{"CompanyId":1,"UpdatedDateUtc":1,_id:0}
},
{"$group":
{"_id": 1,"n": {"$sum": 1}}
}
])
我希望这可以使用这个索引:
{ "CompanyId": -1, "UpdatedDateUtc" : -1 ,"WagerEventDateUtc" : -1 }
但它总是会使用索引:
{ "CompanyId" : 1,"BetDateUtc" : -1, "WagerEventDateUtc" : -1, "UpdatedDateUtc" : -1}
有解释:
{
"nReturned": 101,
"executionTimeMillisEstimate": 0,
"totalKeysExamined": 101,
"totalDocsExamined": 0,
"executionStages": {
"stage": "PROJECTION_COVERED",
"nReturned": 101,
"executionTimeMillisEstimate": 0,
"works": 101,
"advanced": 101,
"needTime": 0,
"needYield": 0,
"saveState": 3,
"restoreState": 2,
"isEOF": 0,
"transformBy": {
"CompanyId": 1,
"UpdatedDateUtc": 1,
"_id": 0
},
"inputStage": {
"stage": "IXSCAN",
"nReturned": 101,
"executionTimeMillisEstimate": 0,
"works": 101,
"advanced": 101,
"needTime": 0,
"needYield": 0,
"saveState": 3,
"restoreState": 2,
"isEOF": 0,
"keyPattern": {
"CompanyId": 1,
"BetDateUtc": -1,
"WagerEventDateUtc": -1,
"UpdatedDateUtc": -1
},
"indexName": "CompanyId_1_BetDateUtc_-1_WagerEventDateUtc_-1_UpdatedDateUtc_-1",
"isMultiKey": false,
"multiKeyPaths": {
"CompanyId": [],
"BetDateUtc": [],
"WagerEventDateUtc": [],
"UpdatedDateUtc": []
},
"isUnique": false,
"isSparse": false,
"isPartial": false,
"indexVersion": 2,
"direction": "forward",
"indexBounds": {
"CompanyId": [
"[1341.0, 1341.0]"
],
"BetDateUtc": [
"[MaxKey, MinKey]"
],
"WagerEventDateUtc": [
"[MaxKey, MinKey]"
],
"UpdatedDateUtc": [
"[new Date(9223372036854775807), new Date(1616715300000)]"
]
},
"keysExamined": 101,
"seeks": 1,
"dupsTested": 0,
"dupsDropped": 0
}
}
},
{
"nReturned": 101,
"executionTimeMillisEstimate": 0,
"totalKeysExamined": 101,
"totalDocsExamined": 0,
"executionStages": {
"stage": "PROJECTION_COVERED",
"nReturned": 101,
"executionTimeMillisEstimate": 0,
"works": 101,
"advanced": 101,
"needTime": 0,
"needYield": 0,
"saveState": 10242,
"restoreState": 10242,
"isEOF": 0,
"transformBy": {
"CompanyId": 1,
"UpdatedDateUtc": 1,
"_id": 0
},
"inputStage": {
"stage": "IXSCAN",
"nReturned": 101,
"executionTimeMillisEstimate": 0,
"works": 101,
"advanced": 101,
"needTime": 0,
"needYield": 0,
"saveState": 10242,
"restoreState": 10242,
"isEOF": 0,
"keyPattern": {
"CompanyId": -1,
"UpdatedDateUtc": -1,
"WagerEventDateUtc": -1
},
"indexName": "CompanyId_-1_UpdatedDateUtc_-1_WagerEventDateUtc_-1",
"isMultiKey": false,
"multiKeyPaths": {
"CompanyId": [],
"UpdatedDateUtc": [],
"WagerEventDateUtc": []
},
"isUnique": false,
"isSparse": false,
"isPartial": false,
"indexVersion": 2,
"direction": "forward",
"indexBounds": {
"CompanyId": [
"[1341.0, 1341.0]"
],
"UpdatedDateUtc": [
"[new Date(9223372036854775807), new Date(1616715300000)]"
],
"WagerEventDateUtc": [
"[MaxKey, MinKey]"
]
},
"keysExamined": 101,
"seeks": 1,
"dupsTested": 0,
"dupsDropped": 0
}
}
}
我认为mongodb选择错误的索引是因为“saveState”和“restoreState”太高了,但我不确定,因为我不知道这两个字段是什么意思。
【问题讨论】:
-
我想知道你的真正问题是什么。如果您仍然需要两个索引,那么让 mongodb 选择它想要使用的任何索引。它已经完美优化,因为检查的键和返回的文档之间的比率是 1。如果您不希望它使用该索引,请尝试删除它并再次运行解释。
-
嗨@SebastianK,我的问题是我的查询过滤器没有 BetDateUtc 和 WagerEventDateUtc,为什么 mongodb 选择 { "CompanyId" : 1,"BetDateUtc" : -1, "WagerEventDateUtc" : -1, " UpdatedDateUtc" : -1} ;它与 mongodb 前缀 doc 不同(docs.mongodb.com/v4.2/core/index-compound/#prefixes)
-
这确实是一个好问题。如果不查看示例集合,我无法回答这个问题。一个补充:您可以使用提示(docs.mongodb.com/manual/reference/operator/meta/hint)强制 mongo db 使用特定索引。
-
嗨@SebastianK,有示例文档: {"_id" : ObjectId("00000000000000000000000"),"CompanyId" : 0000,"WagerId" : NumberLong(000000000),"BetDateUtc" : ISODate ("2021-02-04T05:59:52.405Z"),"UpdatedDateUtc" : ISODate("2021-02-04T06:03:27.551Z"),"SettledDateUtc" : ISODate("2021-02-04T06:03: 27.551Z"),"WagerEventDateUtc" : ISODate("2021-02-04T06:01:03Z")}