No MongoDB, você pode usar o
cursor.explain()
ou o método db.collection.explain()
método para determinar se uma consulta usa ou não um índice. Esses métodos permitem que você exiba o plano de consulta para a consulta, que inclui se ela usa ou não um índice.
Exemplo
Suponha que tenhamos uma coleção chamada
pets
, e contém os seguintes documentos:{ "_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 suponha que criamos o seguinte índice em seu
name
campo:db.pets.createIndex( { "name" : 1 } )
Agora, quando executamos a seguinte consulta, ela deve usar esse índice:
db.pets.find( { "name" : "Scratch" } )
Resultado:
{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }
Mas não podemos dizer apenas olhando os resultados se ele usou o índice ou não.
É aqui que o
explain()
O método entra. Podemos anexar explain()
ao final de nossa consulta para obter o plano de consulta. Isso nos dirá se usou ou não um índice. db.pets.find( { "name" : "Scratch" } ).explain()
Resultado:
{ "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 }
Podemos ver pela parte que lê
IXSCAN
que a consulta usa uma varredura de índice para produzir seus resultados. Por outro lado, se fizermos o mesmo para uma consulta que não está incluída em nosso índice, veremos que ela usa uma varredura de coleção (
COLLSCAN
):db.pets.find( { "type" : "Dog" } ).explain()
Resultado:
{ "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 }
O db.collection.explain()
Método
O
db.collection.explain()
método é semelhante ao cursor.explain()
, exceto que com db.collection.explain()
, você pode encadear modificadores de consulta adicionais à consulta (após o find()
método). Para nossos propósitos, podemos fazer o seguinte:
db.pets.explain().find( { "name": "Scratch" } )
Resultado:
{ "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 }
Você pode executar o seguinte comando para recuperar uma lista de modificadores de consulta disponíveis para este método:
db.collection.explain().find().help()