Analiza la ejecución de consultas con Query Explain

En esta página, se describe cómo recuperar información sobre la ejecución de consultas cuando ejecutas una consulta.

Usa la función Query Explain

Puedes usar Query Explain para comprender cómo se ejecutan tus consultas. Esto proporciona detalles que puedes usar para optimizar tus consultas.

Puedes usar Query Explain a través de la Google Cloud console o el explain comando.

Console

Ejecuta una consulta en el Editor de consultas y abre la pestaña Explicación:

  1. En la Google Cloud console, ve a la página Bases de datos.

    Ir a Bases de datos

  2. En la lista de bases de datos, selecciona una base de datos de Firestore con compatibilidad con MongoDB. Laconsola abre el Explorador de Firestore para esa base de datos. Google Cloud
  3. Ingresa una consulta en el editor de consultas y haz clic en Ejecutar.
  4. Haz clic en la pestaña Explicación para ver el resultado del análisis de la consulta.

    Pestaña Query Explain en la consola
API de MongoDB

La función Query Explain en la API de MongoDB se admite a través del comando explain, que puedes usar en herramientas como Mongo Shell y Compass.

El comando explain es compatible con los comandos aggregate, find, distinct y count, por ejemplo:

db.collection.explain('executionStats').find(...)

También puedes usar el método explain(), por ejemplo:

db.collection.find({QUERY}).explain('executionStats')
Limitaciones
Ten en cuenta las siguientes limitaciones y diferencias:
  • La función Query Explain no admite comandos que devuelven un cursor. Por ejemplo, no se admite invocar la explicación llamando directamente al siguiente comando:

    db.collection.aggregate(..., explain: true)
  • La función Query Explain solo es compatible con los comandos find, aggregate, count, distinct, update, delete y findAndModify.

  • Query Explain admite los modos de detalle executionStats, allPlansExecution y queryPlanner.

    • queryPlanner: Muestra solo el plan de ejecución, sin ejecutar la consulta.
    • executionStats y allPlansExecution: Muestra el plan de ejecución junto con las estadísticas de facturación, memoria y ejecución.

    Si no se especifica ningún modo de detalle, el shell usa queryPlanner de forma predeterminada. Para ver las estadísticas de ejecución completas, debes especificar el modo de detalle executionStats o allPlansExecution.

Análisis

El resultado de Query Explain contiene dos componentes principales: las estadísticas de resumen y el árbol de ejecución. Considera esta consulta como ejemplo:

db.orders.aggregate(
 [
   { "$match": { "user_id": 1234 } },
   { "$sort": { "date_placed": 1 } }
 ]
)

Estadísticas de resumen

La parte superior del resultado explicado contiene un resumen de las estadísticas de ejecución. Usa estas estadísticas para determinar si una búsqueda tiene una latencia o un costo altos. También contiene estadísticas de memoria que te permiten saber qué tan cerca está tu consulta de los límites de memoria.

Execution:
 results returned: 35
 query id: 7e7b37ea1a259d79
 request peak memory usage: 45.56 KiB (46,656 B)
 data bytes read: 24.58 KiB (25,175 B)
 entity row scanned: 265

Billing:
 read units: 7

Árbol de ejecución

El árbol de ejecución describe la ejecución de la consulta como una serie de nodos. Los nodos inferiores (nodos hoja) recuperan datos de la capa de almacenamiento, que recorre el árbol hacia arriba para generar una respuesta a la consulta.

Para obtener detalles sobre cada nodo de ejecución, consulta la referencia de ejecución.

Si deseas obtener detalles para usar esta información y optimizar tus consultas, revisa Optimiza la ejecución de consultas.

A continuación, se muestra un ejemplo de un árbol de ejecución:

Execution:
 results returned: 35
 query id: 7e7b37ea1a259d79
 request peak memory usage: 45.56 KiB (46,656 B)
 data bytes read: 24.58 KiB (25,175 B)
 entity row scanned: 265

Billing:
 read units: 7

Tree:
• Compute
|  $out_1: map_set($record_1, "__id__", $__id___1, "__key__", unset)
|  is query result: true
|
|  Execution:
|   records returned: 35
|   latency: 204.87 ms (local 7.64 ms)
|
└── • Compute
    |  $__id___1: _id($__key___2)
    |
    |  Execution:
    |   records returned: 35
    |   latency: 197.23 ms (local 2.04 ms)
    |
    └── • MajorSort
        |  fields: [$v_5 ASC]
        |  output: [$__key___2, $record_1]
        |
        |  Execution:
        |   records returned: 35
        |   latency: 195.20 ms (local 28.42 ms)
        |   peak memory usage: 45.56 KiB (46,656 B)
        |
        └── • Compute
            |  $v_5: offset($v_4, 0L)
            |
            |  Execution:
            |   records returned: 35
            |   latency: 166.78 ms (local 14.84 ms)
            |
            └── • Compute
                |  $v_4: sortPaths(array($date_placed_1), [date_placed ASC])
                |
                |  Execution:
                |   records returned: 35
                |   latency: 151.94 ms (local 5.43 ms)
                |
                └── • TableScan
                       source: **/orders
                       order: STABLE
                       filter: $eq($user_id_1, 1,234)
                       output bindings: {$__key___2=row().__key__, $date_placed_1=row().date_placed, $record_1=row[* - { __create_time__, __update_time__ }](), $user_id_1=row().user_id}
                       output: [$__key___2, $date_placed_1, $record_1]

                       Execution:
                        records returned: 35
                        latency: 146.50 ms
                        data bytes returned: 3.25 KiB (3,325 B)
                        post-filtered rows: 230
                        records scanned: 265
                        data bytes read: 24.58 KiB (25,175 B)

¿Qué sigue?