I MongoDB kan du bruge cursor.explain()
metoden eller db.collection.explain()
metode til at bestemme, om en forespørgsel bruger et indeks eller ej.
Disse metoder giver dig mulighed for at se forespørgselsplanen for forespørgslen, som inkluderer, om den bruger et indeks eller ej.
Eksempel
Antag, at vi har en samling kaldet pets
, og den indeholder følgende dokumenter:
{ "_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 }
Og antag, at vi opretter følgende indeks på dets name
felt:
db.pets.createIndex( { "name" : 1 } )
Når vi nu kører følgende forespørgsel, skal den bruge det indeks:
db.pets.find( { "name" : "Scratch" } )
Resultat:
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
Men vi kan ikke bare se på resultaterne, om den brugte indekset eller ej.
Det er her explain()
metoden kommer ind. Vi kan tilføje explain()
til slutningen af vores forespørgsel for at få forespørgselsplanen. Det vil fortælle os, om den brugte et indeks eller ej.
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 ved den del, der lyder IXSCAN
at forespørgslen bruger en indeksscanning til at producere sine resultater.
I modsætning hertil, hvis vi gør det samme for en forespørgsel, der ikke er inkluderet i vores indeks, vil vi se, at den bruger en samlingsscanning (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()
Metode
db.collection.explain()
metode ligner cursor.explain()
, bortset fra det med db.collection.explain()
, kan du kæde yderligere forespørgselsmodifikatorer til forespørgslen (efter find()
metode).
Til vores formål kan vi gøre følgende:
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øre følgende kommando for at hente en liste over forespørgselsmodifikatorer, der er tilgængelige for denne metode:
db.collection.explain().find().help()