MongoDb索引优化

时间:2016-08-03 09:22:49

标签: mongodb

我正在使用MongoDB来创建一个项目,该项目存储从日志中解析的一些类似doc的数据,并支持来自MongoDB的一些复杂查询。但是当我运行查询时,我遇到了一个非常有趣的问题。 查询是这样的:

db.actions.find({
    Created: { $gte: 1470208679, $lte: 1470212279 }, 
    ActionType: "COMMENT_CREATE", 
    UserAgent: "osee2unifiedRelease/482 CFNetwork/758.2.8 Darwin/15.0.0" 
}).limit(200)

我构建了两个复合索引,一个是{ ActionType: 1, Created: 1 },另一个是{ UserAgent: 1, Created: 1 }。最初,我认为MongoDB应该找到乐观主义索引来进行查询。但是从日志中,不幸的是它没有。

我使用explain()查找原因。 mongo客户端的结果如下

> db.actions.find({
      Created: { $gte: 1470208679, $lte: 1470212279 }, 
      ActionType: "COMMENT_CREATE", 
      UserAgent: "osee2unifiedRelease/482 CFNetwork/758.2.8 Darwin/15.0.0" 
}).limit(200).explain()

结果

{
    "cursor" : "IndexCursor UserAgent_1_Created_1",
    "isMultiKey" : false,
    "n" : 167,
    "nscannedObjects" : 1552,
    "nscanned" : 1552,
    "nscannedObjectsAllPlans" : 2426,
    "nscannedAllPlans" : 2426,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nChunkSkips" : 0,
    "millis" : 32,
    "indexBounds" : {
        "UserAgent" : [
            [
                "osee2unifiedRelease/482 CFNetwork/758.2.8 Darwin/15.0.0",
                "osee2unifiedRelease/482 CFNetwork/758.2.8 Darwin/15.0.0"
            ]
        ],
        "Created" : [
            [
                1470208679,
                1470212279
            ]
        ]
    },
}

如果我们使用提示来使用另一个索引,结果是

db.actions.find({
    Created: { $gte: 1470208679, $lte: 1470212279 }, 
    ActionType: "COMMENT_CREATE", 
    UserAgent: "osee2unifiedRelease/482 CFNetwork/758.2.8 Darwin/15.0.0" 
}).limit(200).hint({ ActionType: 1, Created: 1 }).explain()

结果

{
    "cursor" : "IndexCursor ActionType_1_Created_1",
    "isMultiKey" : false,
    "n" : 167,
    "nscannedObjects" : 13988,
    "nscanned" : 13988,
    "nscannedObjectsAllPlans" : 13988,
    "nscannedAllPlans" : 13988,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nChunkSkips" : 0,
    "millis" : 127,
    "indexBounds" : {
        "ActionType" : [
            [
                "COMMENT_CREATE",
                "COMMENT_CREATE"
            ]
        ],
        "Created" : [
            [
                1470208679,
                1470212279
            ]
        ]
    },
}

我们可以看到mongo客户端自动使用{ "UserAgent": 1, Created: 1 }索引,这是最佳选择,nscanned远远少于{ 'ActionType': 1, Created: 1 }索引。直到现在,一切似乎都很完美。但是当我们使用项目中的查询而不是mongo命令行时,从日志中发现了奇怪的东西,它选择了 { 'ActionType': 1, Created: 1 }索引。

Wed Aug  3 16:17:59.442 [conn1517] query actions query: { $query: { $and: [ { Created: { $gte: 1470208679 } }, { Created: { $lte: 1470212279} }, { ActionType: "COMMENT_CREATE" }, { UserAgent: "osee2unifiedRelease/482 CFNetwork/758.2.8 Darwin/15.0.0" } ] }} ntoreturn:200 ntoskip:0 nscanned:13988 keyUpdates:0 locks(micros) r:147591 nreturned:167 reslen:68229 147ms

任何人都可以帮我解决这个问题吗?

0 个答案:

没有答案