Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt — versiones en markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
Docs Menu

Interpreta los resultados del plan de explicación

Puedes usar los resultados de 'explain' para determinar la siguiente información sobre una consulta:

  • La cantidad de tiempo que tardó en completarse una query

  • Si la query usó o no un índice.

  • El número de documentos y claves de índice escaneados para cumplir con una query

Nota

Los resultados del plan de explicación para las consultas están sujetos a cambios entre las versiones de MongoDB.

Los métodos cursor.explain("executionStats") y db.collection.explain("executionStats") proporcionan estadísticas sobre el rendimiento de una consulta. Estas estadísticas pueden ser útiles para medir si una consulta utiliza un índice y cómo lo hace. Consulta db.collection.explain() para más detalles.

Considera una colección inventory con los siguientes documentos:

db.inventory.insertMany ( [
{ _id: 1, item: "f1", type: "food", quantity: 500 },
{ _id: 2, item: "f2", type: "food", quantity: 100 },
{ _id: 3, item: "p1", type: "paper", quantity: 200 },
{ _id: 4, item: "p2", type: "paper", quantity: 150 },
{ _id: 5, item: "f3", type: "food", quantity: 300 },
{ _id: 6, item: "t1", type: "toys", quantity: 500 },
{ _id: 7, item: "a1", type: "apparel", quantity: 250 },
{ _id: 8, item: "a2", type: "apparel", quantity: 400 },
{ _id: 9, item: "t2", type: "toys", quantity: 50 },
{ _id: 10, item: "f4", type: "food", quantity: 75 }
] )

La siguiente query recupera documentos donde el campo quantity tiene un valor entre 100 y 200, inclusivo:

db.inventory.find( { quantity: { $gte: 100, $lte: 200 } } )

La query devuelve los siguientes documentos:

{ "_id" : 2, "item" : "f2", "type" : "food", "quantity" : 100 }
{ "_id" : 3, "item" : "p1", "type" : "paper", "quantity" : 200 }
{ "_id" : 4, "item" : "p2", "type" : "paper", "quantity" : 150 }

Para ver el plan del query seleccionado, encadena el método cursor cursor.explain("executionStats") al final del comando find:

db.inventory.find(
{ quantity: { $gte: 100, $lte: 200 } }
).explain("executionStats")

explain() devuelve los siguientes resultados:

{
queryPlanner: {
...
winningPlan: {
queryPlan: {
stage: 'COLLSCAN',
...
}
}
},
executionStats: {
executionSuccess: true,
nReturned: 3,
executionTimeMillis: 0,
totalKeysExamined: 0,
totalDocsExamined: 10,
executionStages: {
stage: 'COLLSCAN',
...
},
...
},
...
}
  • queryPlanner.winningPlan.queryPlan.stage muestra COLLSCAN para indicar un escaneo de colección.

    El escaneo de colección indica que la mongod tuvo que escanear toda la colección documento por documento para identificar los resultados. Esta es una operación generalmente costosa y puede resultar en consultas lentas.

  • executionStats.nReturned muestra 3 para indicar que el plan del query ganador devuelve tres documentos.

  • executionStats.totalKeysExamined muestra 0 para indicar que esta query no está usando el índice.

  • executionStats.totalDocsExamined exhibe 10 para indicar que MongoDB tuvo que escanear diez documentos (es decir, todos los documentos de la colección) para encontrar los tres documentos coincidentes.

La diferencia entre el número de documentos coincidentes y el número de documentos examinados puede sugerir que, para mejorar la eficiencia, la query podría beneficiarse del uso de un índice.

Para admitir la query en el campo quantity, añada un índice en el campo quantity:

db.inventory.createIndex( { quantity: 1 } )

Para ver las estadísticas del plan del query, utiliza el método explain():

db.inventory.find(
{ quantity: { $gte: 100, $lte: 200 } }
).explain("executionStats")

El método explain() devuelve los siguientes resultados:

{
queryPlanner: {
...
winningPlan: {
queryPlan: {
stage: 'FETCH',
inputStage: {
stage: 'IXSCAN',
keyPattern: {
quantity: 1
},
...
}
}
},
rejectedPlans: [ ]
},
executionStats: {
executionSuccess: true,
nReturned: 3,
executionTimeMillis: 0,
totalKeysExamined: 3,
totalDocsExamined: 3,
executionStages: {
...
},
...
},
...
}
  • queryPlanner.winningPlan.queryPlan.inputStage.stage muestra IXSCAN para indicar el uso del índice.

  • executionStats.nReturned muestra 3 para indicar que el plan del query ganador devuelve tres documentos.

  • executionStats.totalKeysExamined muestra 3 para indicar que MongoDB escaneó tres entradas de índice. La cantidad de llaves examinadas coincide con la cantidad de documentos devueltos, lo que significa que mongod solo tuvo que examinar las llaves de índice para devolver los resultados. El mongod no tuvo que escanear todos los documentos, y solo fue necesario extraer a la memoria los tres documentos coincidentes. Esto da como resultado una consulta muy eficiente.

  • executionStats.totalDocsExamined mostrar 3 para indicar que MongoDB ha analizado tres documentos.

Sin el índice, la query sería escanear toda la colección de 10 documentos para devolver 3 documentos coincidentes. La query también tenía que escanear la totalidad de cada documento, potencialmente llevándolos a la memoria. Esto da como resultado una operación de query costosa y potencialmente lenta.

Cuando se ejecutó con un índice, la query escaneó 3 entradas de índice y 3 documentos para devolver 3 documentos coincidentes, lo que resultó en una query muy eficiente.

Comparar el funcionamiento de los índices

Para comparar manualmente el rendimiento de una query utilizando más de un índice, puedes utilizar el hint() método junto con el explain() método.

Considera el siguiente query:

db.inventory.find( {
quantity: {
$gte: 100, $lte: 300
},
type: "food"
} )

La query devuelve los siguientes documentos:

{ "_id" : 2, "item" : "f2", "type" : "food", "quantity" : 100 }
{ "_id" : 5, "item" : "f3", "type" : "food", "quantity" : 300 }

Para respaldar la query, agregue un índice compuesto. Con los índices compuestos, el orden de los campos es importante.

Por ejemplo, añade los siguientes dos índices compuestos. El primer índice ordena primero por el campo quantity y luego por el campo type. El segundo índice ordena primero por type y luego por el campo quantity.

db.inventory.createIndex( { quantity: 1, type: 1 } )
db.inventory.createIndex( { type: 1, quantity: 1 } )

Evalúa el efecto del primer índice en la query:

db.inventory.find(
{ quantity: { $gte: 100, $lte: 300 }, type: "food" }
).hint({ quantity: 1, type: 1 }).explain("executionStats")

El método explain() devuelve la siguiente salida:

{
queryPlanner: {
...
winningPlan: {
queryPlan: {
stage: 'FETCH',
inputStage: {
stage: 'IXSCAN',
keyPattern: {
quantity: 1,
type: 1
},
...
}
}
}
},
rejectedPlans: [ ]
},
executionStats: {
executionSuccess: true,
nReturned: 2,
executionTimeMillis: 0,
totalKeysExamined: 5,
totalDocsExamined: 2,
executionStages: {
...
}
},
...
}

MongoDB analizó 5 claves del índice (executionStats.totalKeysExamined) para devolver 2 documentos coincidentes (executionStats.nReturned).

Evaluar el efecto del segundo índice en la query:

db.inventory.find(
{ quantity: { $gte: 100, $lte: 300 }, type: "food" }
).hint({ type: 1, quantity: 1 }).explain("executionStats")

El método explain() devuelve la siguiente salida:

{
queryPlanner: {
...
queryPlan: {
winningPlan: {
stage: 'FETCH',
inputStage: {
stage: 'IXSCAN',
keyPattern: {
type: 1,
quantity: 1
},
...
}
}
},
rejectedPlans: [ ]
},
executionStats: {
executionSuccess: true,
nReturned: 2,
executionTimeMillis: 0,
totalKeysExamined: 2,
totalDocsExamined: 2,
executionStages: {
...
}
},
...
}

MongoDB analizó 2 claves del índice (executionStats.totalKeysExamined) para devolver 2 documentos coincidentes (executionStats.nReturned).

Por lo tanto, el segundo índice compuesto, { type: 1, quantity: 1 }, es el índice más eficiente para respaldar la query de ejemplo, ya que el servidor de MongoDB solo necesita escanear 2 index keys para encontrar todos los documentos coincidentes usando este índice, en comparación con 5 al usar el índice compuesto { quantity: 1, type: 1 }.

Califique esta página