I MongoDB kan du använda cursor.explain()
metoden eller db.collection.explain()
metod för att avgöra om en fråga använder ett index eller inte.
Dessa metoder gör att du kan se frågeplanen för frågan, som inkluderar om den använder ett index eller inte.
Exempel
Anta att vi har en samling som heter pets
, och den innehåller följande dokument:
{ "_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 }
Och anta att vi skapar följande index på dess name
fält:
db.pets.createIndex( { "name" : 1 } )
Nu när vi kör följande fråga bör den använda det indexet:
db.pets.find( { "name" : "Scratch" } )
Resultat:
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
Men vi kan inte avgöra bara genom att titta på resultaten om det använde indexet eller inte.
Det är här explain()
metod kommer in. Vi kan lägga till explain()
till slutet av vår fråga för att få frågeplanen. Det kommer att berätta för oss om den använde ett index eller inte.
db.pets.find( { "name" : "Scratch" } ).explain()
Resultat:
{ "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 }
Vi kan se av delen som läser IXSCAN
att frågan använder en indexskanning för att producera sina resultat.
Om vi däremot gör samma sak för en fråga som inte ingår i vårt index, kommer vi att se att den använder en samlingsskanning (COLLSCAN
):
db.pets.find( { "type" : "Dog" } ).explain()
Resultat:
{ "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 }
Den db.collection.explain()
Metod
db.collection.explain()
metod liknar cursor.explain()
, förutom det med db.collection.explain()
, kan du koppla ytterligare frågemodifierare till frågan (efter find()
metod).
För våra ändamål kan vi göra följande:
db.pets.explain().find( { "name": "Scratch" } )
Resultat:
{ "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 }
Du kan köra följande kommando för att hämta en lista över frågemodifierare som är tillgängliga för den här metoden:
db.collection.explain().find().help()