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()