In MongoDB, puoi usare cursor.explain()
o il metodo db.collection.explain()
metodo per determinare se una query utilizza o meno un indice.
Questi metodi consentono di visualizzare il piano di query per la query, che include l'utilizzo o meno di un indice.
Esempio
Supponiamo di avere una collezione chiamata pets
, e contiene i seguenti documenti:
{ "_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 }
E supponiamo di creare il seguente indice sul suo name
campo:
db.pets.createIndex( { "name" : 1 } )
Ora, quando eseguiamo la seguente query, dovrebbe utilizzare quell'indice:
db.pets.find( { "name" : "Scratch" } )
Risultato:
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
Ma non possiamo dire solo guardando i risultati se ha utilizzato l'indice o meno.
Qui è dove il explain()
entra in gioco. Possiamo aggiungere explain()
alla fine della nostra query per ottenere il piano di query. Questo ci dirà se ha utilizzato o meno un indice.
db.pets.find( { "name" : "Scratch" } ).explain()
Risultato:
{ "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 }
Possiamo vedere dalla parte che legge IXSCAN
che la query utilizza una scansione dell'indice per produrre i risultati.
Al contrario, se facciamo lo stesso per una query che non è inclusa nel nostro indice, vedremo che utilizza una scansione raccolta (COLLSCAN
):
db.pets.find( { "type" : "Dog" } ).explain()
Risultato:
{ "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 }
Il db.collection.explain()
Metodo
Il db.collection.explain()
il metodo è simile a cursor.explain()
, tranne quello con db.collection.explain()
, puoi concatenare ulteriori modificatori di query alla query (dopo find()
metodo).
Per i nostri scopi, possiamo fare quanto segue:
db.pets.explain().find( { "name": "Scratch" } )
Risultato:
{ "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 }
Puoi eseguire il comando seguente per recuperare un elenco di modificatori di query disponibili per questo metodo:
db.collection.explain().find().help()