【问题标题】:mongodb not follow prefix rulemongodb不遵循前缀规则
【发布时间】: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")}

标签: mongodb indexing


【解决方案1】:

为什么选择一个索引而不是另一个的答案是它运行一个简短的测试,计算每个“工作”单元返回最多结果的索引,以及在测试期间完成或不使用阻塞排序的奖励积分。

如果之后有 2 个或多个索引被绑定,它会随机选择一个。

【讨论】:

    猜你喜欢
    • 2020-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-23
    • 2020-09-26
    相关资源
    最近更新 更多