sql >> Base de Datos >  >> NoSQL >> MongoDB

Averigüe si una consulta usa un índice en MongoDB

En MongoDB, puede usar el cursor.explain() método o db.collection.explain() para determinar si una consulta utiliza o no un índice.

Estos métodos le permiten ver el plan de consulta para la consulta, que incluye si usa o no un índice.

Ejemplo

Supongamos que tenemos una colección llamada pets , y contiene los siguientes 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 }

Y supongamos que creamos el siguiente índice en su name campo:

db.pets.createIndex( { "name" : 1 } )

Ahora, cuando ejecutemos la siguiente consulta, debería usar ese índice:

db.pets.find( { "name" : "Scratch" } )

Resultado:

{ "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 }

Pero no podemos saber con solo mirar los resultados si usó el índice o no.

Aquí es donde explain() entra el método. Podemos añadir explain() al final de nuestra consulta para obtener el plan de consulta. Eso nos dirá si usó o no un í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 por la parte que dice IXSCAN que la consulta utiliza un escaneo de índice para producir sus resultados.

En cambio, si hacemos lo mismo con una consulta que no está incluida en nuestro índice, veremos que utiliza un escaneo de colección (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
}

El db.collection.explain() Método

db.collection.explain() el método es similar a cursor.explain() , excepto que con db.collection.explain() , puede encadenar modificadores de consulta adicionales a la consulta (después de find() método).

Para nuestros propósitos, podemos hacer lo siguiente:

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
}

Puede ejecutar el siguiente comando para recuperar una lista de modificadores de consulta disponibles para este método:

db.collection.explain().find().help()