了解查询是否使用 MongoDB 中的索引
在 MongoDB 中,您可以使用该方法或方法来确定查询是否使用索引。cursor.explain()``db.collection.explain()
通过这些方法,可以查看查询的查询计划,其中包括查询是否使用索引。
例
假设我们有一个名为 的集合,它包含以下文档:pets
{ “_id” : 1, “name” : “Wag”, “type” : “Dog”, “weight” : 20 } { “_id” : 2, “name” : “Bark”, “type” : “Dog”, “weight” : 10 } { “_id” : 3, “name” : “Meow”, “type” : “Cat”, “weight” : 7 } { “_id” : 4, “name” : “Scratch”, “type” : “Cat”, “weight” : 8 } { “_id” : 5, “name” : “Bruce”, “type” : “Bat”, “weight” : 3 } { “_id” : 6, “name” : “Fetch”, “type” : “Dog”, “weight” : 17 } { “_id” : 7, “name” : “Jake”, “type” : “Dog”, “weight” : 30 }
假设我们在其字段上创建以下索引:name
db.pets.createIndex( { "name" : 1 } )
现在,当我们运行以下查询时,它应该使用该索引:
db.pets.find( { "name" : "Scratch" } )
结果:
{ “_id” : 4, “name” : “Scratch”, “type” : “Cat”, “weight” : 8 }
但是我们不能仅仅通过查看结果来判断它是否使用了索引。
这就是方法的用武之地。我们可以追加到查询的末尾以获取查询计划。这将告诉我们它是否使用了索引。explain()``explain()
db.pets.find( { "name" : "Scratch" } ).explain()
结果:
{ “queryPlanner” : { “plannerVersion” : 1, “namespace” : “PetHouse.pets”, “indexFilterSet” : false, “parsedQuery” : { “name” : { “$eq” : “Scratch” } }, “queryHash” : “01AEE5EC”, “planCacheKey” : “4C5AEA2C”, “winningPlan” : { “stage” : “FETCH”, “inputStage” : { “stage” : “IXSCAN”, “keyPattern” : { “name” : 1 }, “indexName” : “name_1”, “isMultiKey” : false, “multiKeyPaths” : { “name” : [ ] }, “isUnique” : false, “isSparse” : false, “isPartial” : false, “indexVersion” : 2, “direction” : “forward”, “indexBounds” : { “name” : [ “["Scratch", "Scratch"]” ] } } }, “rejectedPlans” : [ ] }, “ok” : 1 }
我们可以通过读取的部分看到查询使用索引扫描来生成其结果。IXSCAN
相反,如果我们对未包含在索引中的查询执行相同的操作,我们将看到它使用集合扫描 ():COLLSCAN
db.pets.find( { "type" : "Dog" } ).explain()
结果:
{ “queryPlanner” : { “plannerVersion” : 1, “namespace” : “PetHouse.pets”, “indexFilterSet” : false, “parsedQuery” : { “type” : { “$eq” : “Dog” } }, “queryHash” : “2A1623C7”, “planCacheKey” : “2A1623C7”, “winningPlan” : { “stage” : “COLLSCAN”, “filter” : { “type” : { “$eq” : “Dog” } }, “direction” : “forward” }, “rejectedPlans” : [ ] }, “ok” : 1 }
方法db.collection.explain()
该方法与 类似,不同之处在于 可以将其他查询修饰符链接到查询(在方法之后)。db.collection.explain()``cursor.explain()``db.collection.explain()``find()
出于我们的目的,我们可以执行以下操作:
db.pets.explain().find( { "name": "Scratch" } )
结果:
{ “queryPlanner” : { “plannerVersion” : 1, “namespace” : “PetHouse.pets”, “indexFilterSet” : false, “parsedQuery” : { “name” : { “$eq” : “Scratch” } }, “queryHash” : “01AEE5EC”, “planCacheKey” : “4C5AEA2C”, “winningPlan” : { “stage” : “FETCH”, “inputStage” : { “stage” : “IXSCAN”, “keyPattern” : { “name” : 1 }, “indexName” : “name_1”, “isMultiKey” : false, “multiKeyPaths” : { “name” : [ ] }, “isUnique” : false, “isSparse” : false, “isPartial” : false, “indexVersion” : 2, “direction” : “forward”, “indexBounds” : { “name” : [ “["Scratch", "Scratch"]” ] } } }, “rejectedPlans” : [ ] }, “ok” : 1 }
可以运行以下命令来检索可用于此方法的查询修饰符列表:
db.collection.explain().find().help()