使用索引排序MongoDB

时间:2018-02-15 03:00:27

标签: mongodb

以下是我想让您看到的集合的索引状态的状态。

> db.histories.getIndexes();
[
  {
    "v" : 1,
    "key" : {
      "_id" : 1
    },
    "name" : "_id_",
    "ns" : "development.histories"
  },
  {
    "v" : 1,
    "key" : {
      "hoge_id" : 1,
      "created_at" : 1
    },
    "name" : "hoge_id_1_created_at_1",
    "ns" : "development.histories",
    "background" : true
  },
  {
    "v" : 1,
    "key" : {
      "created_at" : 1
    },
    "name" : "created_at_1",
    "ns" : "development.histories",
    "background" : true
  }
]

并且,我执行了以下查询。

> db.histories.find({hoge_id: ObjectId("5a5c171010ebfb1a2c901008")}).sort( { created_at: -1 } ).limit(1).explain("executionStats");

结果如下。

{
  "queryPlanner" : {
    "plannerVersion" : 1,
    "namespace" : "development.histories",
    "indexFilterSet" : false,
    "parsedQuery" : {
      "hoge_id" : {
        "$eq" : ObjectId("5a5c171010ebfb1a2c901008")
      }
    },
    "winningPlan" : {
      "stage" : "LIMIT",
      "limitAmount" : 1,
      "inputStage" : {
        "stage" : "FETCH",
        "inputStage" : {
          "stage" : "IXSCAN",
          "keyPattern" : {
            "hoge_id" : 1,
            "created_at" : 1
          },
          "indexName" : "hoge_id_1_created_at_1",
          "isMultiKey" : false,
          "isUnique" : false,
          "isSparse" : false,
          "isPartial" : false,
          "indexVersion" : 1,
          "direction" : "backward",
          "indexBounds" : {
            "hoge_id" : [
              "[ObjectId('5a5c171010ebfb1a2c901008'), ObjectId('5a5c171010ebfb1a2c901008')]"
            ],
            "created_at" : [
              "[MaxKey, MinKey]"
            ]
          }
        }
      }
    },
    "rejectedPlans" : [ ]
  },
  "executionStats" : {
    "executionSuccess" : true,
    "nReturned" : 1,
    "executionTimeMillis" : 0,
    "totalKeysExamined" : 1,
    "totalDocsExamined" : 1,
    "executionStages" : {
      "stage" : "LIMIT",
      "nReturned" : 1,
      "executionTimeMillisEstimate" : 0,
      "works" : 2,
      "advanced" : 1,
      "needTime" : 0,
      "needYield" : 0,
      "saveState" : 0,
      "restoreState" : 0,
      "isEOF" : 1,
      "invalidates" : 0,
      "limitAmount" : 1,
      "inputStage" : {
        "stage" : "FETCH",
        "nReturned" : 1,
        "executionTimeMillisEstimate" : 0,
        "works" : 1,
        "advanced" : 1,
        "needTime" : 0,
        "needYield" : 0,
        "saveState" : 0,
        "restoreState" : 0,
        "isEOF" : 0,
        "invalidates" : 0,
        "docsExamined" : 1,
        "alreadyHasObj" : 0,
        "inputStage" : {
          "stage" : "IXSCAN",
          "nReturned" : 1,
          "executionTimeMillisEstimate" : 0,
          "works" : 1,
          "advanced" : 1,
          "needTime" : 0,
          "needYield" : 0,
          "saveState" : 0,
          "restoreState" : 0,
          "isEOF" : 0,
          "invalidates" : 0,
          "keyPattern" : {
            "hoge_id" : 1,
            "created_at" : 1
          },
          "indexName" : "hoge_id_1_created_at_1",
          "isMultiKey" : false,
          "isUnique" : false,
          "isSparse" : false,
          "isPartial" : false,
          "indexVersion" : 1,
          "direction" : "backward",
          "indexBounds" : {
            "hoge_id" : [
              "[ObjectId('5a5c171010ebfb1a2c901008'), ObjectId('5a5c171010ebfb1a2c901008')]"
            ],
            "created_at" : [
              "[MaxKey, MinKey]"
            ]
          },
          "keysExamined" : 1,
          "dupsTested" : 0,
          "dupsDropped" : 0,
          "seenInvalidated" : 0
        }
      }
    }
  },
  "serverInfo" : {
    "host" : "b9cb1b8d1fc1",
    "port" : 27017,
    "version" : "3.2.18",
    "gitVersion" : "4c1bae566c0c00f996a2feb16febf84936ecaf6f"
  },
  "ok" : 1
}

结果很快,我想是因为在created_at上创建了索引。

REF。 "totalDocsExamined" : 1"executionTimeMillis" : 0

然后,我确实执行了以下查询。以前的差异是用于sort的字段。

> db.histories.find({hoge_id: ObjectId("5a5c171010ebfb1a2c901008")}).sort( { id: -1 } ).limit(1).explain("executionStats"); 

结果如下。

> db.histories.find({hoge_id: ObjectId("5a5c171010ebfb1a2c901008")}).sort( { id: -1 } ).limit(1).explain("executionStats");
{
  "queryPlanner" : {
    "plannerVersion" : 1,
    "namespace" : "development.histories",
    "indexFilterSet" : false,
    "parsedQuery" : {
      "hoge_id" : {
        "$eq" : ObjectId("5a5c171010ebfb1a2c901008")
      }
    },
    "winningPlan" : {
      "stage" : "SORT",
      "sortPattern" : {
        "id" : -1
      },
      "limitAmount" : 1,
      "inputStage" : {
        "stage" : "SORT_KEY_GENERATOR",
        "inputStage" : {
          "stage" : "FETCH",
          "inputStage" : {
            "stage" : "IXSCAN",
            "keyPattern" : {
              "hoge_id" : 1,
              "created_at" : 1
            },
            "indexName" : "hoge_id_1_created_at_1",
            "isMultiKey" : false,
            "isUnique" : false,
            "isSparse" : false,
            "isPartial" : false,
            "indexVersion" : 1,
            "direction" : "forward",
            "indexBounds" : {
              "hoge_id" : [
                "[ObjectId('5a5c171010ebfb1a2c901008'), ObjectId('5a5c171010ebfb1a2c901008')]"
              ],
              "created_at" : [
                "[MinKey, MaxKey]"
              ]
            }
          }
        }
      }
    },
    "rejectedPlans" : [ ]
  },
  "executionStats" : {
    "executionSuccess" : true,
    "nReturned" : 1,
    "executionTimeMillis" : 1215,
    "totalKeysExamined" : 1034353,
    "totalDocsExamined" : 1034353,
    "executionStages" : {
      "stage" : "SORT",
      "nReturned" : 1,
      "executionTimeMillisEstimate" : 1120,
      "works" : 1034357,
      "advanced" : 1,
      "needTime" : 1034355,
      "needYield" : 0,
      "saveState" : 8080,
      "restoreState" : 8080,
      "isEOF" : 1,
      "invalidates" : 0,
      "sortPattern" : {
        "id" : -1
      },
      "memUsage" : 297,
      "memLimit" : 33554432,
      "limitAmount" : 1,
      "inputStage" : {
        "stage" : "SORT_KEY_GENERATOR",
        "nReturned" : 0,
        "executionTimeMillisEstimate" : 950,
        "works" : 1034355,
        "advanced" : 0,
        "needTime" : 1,
        "needYield" : 0,
        "saveState" : 8080,
        "restoreState" : 8080,
        "isEOF" : 1,
        "invalidates" : 0,
        "inputStage" : {
          "stage" : "FETCH",
          "nReturned" : 1034353,
          "executionTimeMillisEstimate" : 650,
          "works" : 1034354,
          "advanced" : 1034353,
          "needTime" : 0,
          "needYield" : 0,
          "saveState" : 8080,
          "restoreState" : 8080,
          "isEOF" : 1,
          "invalidates" : 0,
          "docsExamined" : 1034353,
          "alreadyHasObj" : 0,
          "inputStage" : {
            "stage" : "IXSCAN",
            "nReturned" : 1034353,
            "executionTimeMillisEstimate" : 330,
            "works" : 1034354,
            "advanced" : 1034353,
            "needTime" : 0,
            "needYield" : 0,
            "saveState" : 8080,
            "restoreState" : 8080,
            "isEOF" : 1,
            "invalidates" : 0,
            "keyPattern" : {
              "hoge_id" : 1,
              "created_at" : 1
            },
            "indexName" : "hoge_id_1_created_at_1",
            "isMultiKey" : false,
            "isUnique" : false,
            "isSparse" : false,
            "isPartial" : false,
            "indexVersion" : 1,
            "direction" : "forward",
            "indexBounds" : {
              "hoge_id" : [
                "[ObjectId('5a5c171010ebfb1a2c901008'), ObjectId('5a5c171010ebfb1a2c901008')]"
              ],
              "created_at" : [
                "[MinKey, MaxKey]"
              ]
            },
            "keysExamined" : 1034353,
            "dupsTested" : 0,
            "dupsDropped" : 0,
            "seenInvalidated" : 0
          }
        }
      }
    }
  },
  "serverInfo" : {
    "host" : "b9cb1b8d1fc1",
    "port" : 27017,
    "version" : "3.2.18",
    "gitVersion" : "4c1bae566c0c00f996a2feb16febf84936ecaf6f"
  },
  "ok" : 1
}
>

这次结果很晚。

REF。 "totalDocsExamined" : 1034353"executionTimeMillis" : 1215

关于totalDocsExamined,这些都在所有文件中。

请注意id为索引启用created_at,但是,当使用id对其进行排序时,结果会延迟?

1 个答案:

答案 0 :(得分:1)

第一次查询:

db.histories.find({hoge_id: ObjectId("5a5c171010ebfb1a2c901008")}).sort( { created_at: -1 } ).limit(1).explain("executionStats");

MongoDB通过在hoge_idcreated_at上使用复合索引来优化性能。它首先查看hoge_id,然后使用created_at索引对查询结果进行排序。这样,由于复合索引的有效使用,排序操作可以非常快。

但是,对于您的第二个查询:

db.histories.find({hoge_id: ObjectId("5a5c171010ebfb1a2c901008")}).sort( { id: -1 } ).limit(1).explain("executionStats");

由于hoge_idid上没有复合索引(id上只有一个索引),因此MongoDB实际上是按id手动排序结果。< / p>

有关使用复合索引进行排序的更多信息,请参见here