4

我有一个设置了以下索引的设备集合:

{
  "v" : 1,
  "key" :
  { "sdk.id" : 1, 
    "sdk.createdAt" : 1, 
    "sdk.updatedAt" : 1, 
    "deviceInfo.isTablet" : 1 },
  "name" : "sdk.id_1_sdk.createdAt_1_sdk.updatedAt_1_deviceInfo.isTablet_1",
  "ns" : "company.Device"
}

我的文件是这样的:

{
   _id: ObjectId("something"),
   property: 'abcd',
   sdk: [
      { id: 'ab', createdAt: new Date(), updatedAt: new Date()},
      { id: 'ac', createdAt: new Date(), updatedAt: new Date()},
   ]
}

当我这样做时,db.Device.explain(1).find({'sdk.id': 'ab'}).count()我得到:

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "company.Device",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "sdk.id" : {
                "$eq" : "ab"
            }
        },
        "winningPlan" : {
            "stage" : "COUNT",
            "inputStage" : {
                "stage" : "COUNT_SCAN",
                "keyPattern" : {
                    "sdk.id" : 1,
                    "sdk.createdAt" : 1,
                    "sdk.updatedAt" : 1,
                    "deviceInfo.isTablet" : 1
                },
                "indexName" : "sdk.id_1_sdk.createdAt_1_sdk.updatedAt_1_deviceInfo.isTablet_1",
                "isMultiKey" : true
            }
        },
        "rejectedPlans" : [ ]
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 0,
        "executionTimeMillis" : 712,
        "totalKeysExamined" : 569865,
        "totalDocsExamined" : 0,
        "executionStages" : {
            "stage" : "COUNT",
            "nReturned" : 0,
            "executionTimeMillisEstimate" : 636,
            "works" : 569865,
            "advanced" : 0,
            "needTime" : 569864,
            "needFetch" : 0,
            "saveState" : 4452,
            "restoreState" : 4452,
            "isEOF" : 1,
            "invalidates" : 0,
            "nCounted" : 569863,
            "nSkipped" : 0,
            "inputStage" : {
                "stage" : "COUNT_SCAN",
                "nReturned" : 569863,
                "executionTimeMillisEstimate" : 616,
                "works" : 569864,
                "advanced" : 569863,
                "needTime" : 1,
                "needFetch" : 0,
                "saveState" : 4452,
                "restoreState" : 4452,
                "isEOF" : 1,
                "invalidates" : 0,
                "keysExamined" : 569865,
                "keyPattern" : {
                    "sdk.id" : 1,
                    "sdk.createdAt" : 1,
                    "sdk.updatedAt" : 1,
                    "deviceInfo.isTablet" : 1
                },
                "indexName" : "sdk.id_1_sdk.createdAt_1_sdk.updatedAt_1_deviceInfo.isTablet_1",
                "isMultiKey" : true
            }
        },
        "allPlansExecution" : [ ]
    },
    "serverInfo" : {
        "host" : "rs-primary",
        "port" : 27000,
        "version" : "3.0.2",
        "gitVersion" : "6201872043ecbbc0a4cc169b5482dcf385fc464f"
    },
    "ok" : 1
}

如您所见,请求非常缓慢,并且仅在我们切换到 WiredTiger 后才出现(之前是立即)。

该集合包含约 60 万个文档,并且有约 55 万个带有sdk.id$eq ab 的文档。

有人可以解释我上面的解释吗?我找不到有关 isEOF、saveState 和 restoreState 的任何信息

谢谢

4

1 回答 1

1

isEOF:指定执行阶段是否已到达流的末尾

saveState 和 restoreState:在 Mongo 3.0 中,这些是查询阶段产生(saveState)然后恢复(restoreState)的次数的计数器。例如,收集扫描 (COLLSCAN) 阶段可能需要让步以获取尚未在内存中的文档。查询也会产生,因此它们可以与其他查询交错并通过 $maxTimeMS 或 kill 操作安全地停止。

这些数字本身并不是很有趣。如果您对同一查询运行多个连续的解释,您会注意到数字会根据当时的其他操作以及当时是否所有必需的文档都在内存中而发生变化。

于 2015-09-27T05:14:48.857 回答