Cette page décrit la sortie d'une requête exécutée avec Query Explain. Pour savoir comment exécuter une requête avec Query Explain, consultez Analyser l'exécution des requêtes avec Query Explain.
Concepts courants
Les concepts et termes courants suivants sont utilisés dans l'arborescence d'exécution.
Lignes et enregistrements
Les termes ligne et enregistrement sont utilisés de manière générique pour faire référence à une entrée de document ou d'index.
Variables
$ désigne une variable, qui est créée ou
référencée dans l'arborescence d'exécution. Exemple : $foo_1. Ces variables sont généralement utilisées pour
faire référence au contenu d'un document ou à la valeur d'une expression évaluée
lors de l'exécution d'une requête.
Les variables internes suivantes peuvent apparaître dans les nœuds d'exécution :
$__key__: la clé est un identifiant interne d'un document. Il s'agit d'un identifiant absolu et unique avec le projet, la base de données et le chemin d'accès complet du document.$__id__: l'ID est un identifiant unique d'un document dans sa collection. Il est unique dans une seule collection.$rid: l'ID de ligne est un identifiant interne d'un document dans le stockage. Il est unique dans une seule collection.
Prenons l'exemple d'un nœud Compute utilisé pour calculer le __id__ à partir du document __key__ :
Compute
| $__id__1: _id($__key__)
| records returned: 1
Contraintes et plages
Certains nœuds d'analyse utilisent les attributs constraints et ranges pour décrire la plage de valeurs analysées. Ces attributs utilisent un format d'arborescence de plages qui contient une liste de valeurs. Ces valeurs correspondent à la liste ordonnée de clés qui apparaissent dans la définition de l'index. Par exemple, la première plage qui apparaît
dans l'arborescence, ici (1..5], correspond aux contraintes sur la première clé,
ici a, dans la liste ordonnée de clés :
| index: type=CollectionGroupIndex, id=CICAgOjXh#EK, keys=[a ASC, b ASC, __key__ ASC]
| constraints: /
|----(1..5]
|----[1L]
Chaque niveau d'indentation indique la contrainte qui s'applique à la clé suivante de la liste. Les crochets représentent une plage inclusive, tandis que les parenthèses représentent une plage exclusive. Dans ce cas, la contrainte se traduit par 1 < "a" <= 5 et
"b" = 1.
Dans l'exemple suivant avec plusieurs branches pour a,
la contrainte correspond à 1 < a <= 5 OR a = 10 :
| constraints: /
|----(1L, 5L]
|----[10L]
Variables clés
Dans certains nœuds d'analyse (tels que SequentialScan), il existe à la fois une liste de clés dans l'attribut index et un attribut keys distinct dans le nœud Scan. L'attribut keys du nœud Scan indique le nom de variable de chaque clé dans la définition de l'index, dans l'ordre. Les variables peuvent être utilisées pour référencer les valeurs d'exécution du champ analysé plus haut dans l'arborescence d'exécution.
Dans l'exemple suivant, la valeur du champ user pour le document actuel
est mappée à la variable $user_1, et la valeur de date_placed à $date_placed_1.
index: type=CollectionGroupIndex, id=CICAgOjXh4EK, keys=[user ASC, date_placed ASC, __key__ ASC]
keys: [user ASC, date_placed ASC, __key__ ASC]
Nœuds d'exécution
Une arborescence d'exécution de requête peut contenir les nœuds suivants.
SeekingScan
Représente une analyse dynamique dans laquelle les lignes renvoyées peuvent ne pas se trouver dans une seule plage séquentielle de l'index, et plusieurs analyses distinctes doivent être effectuées pour satisfaire la requête.
Par exemple, une requête où a existe et b est égal à 1 fonctionnant sur un
index de ["a" ASC, "b" ASC], devrait analyser et renvoyer une plage distincte,
potentiellement non séquentielle, pour chaque valeur distincte de a.
Cette méthode est plus efficace qu'une TableScan complète, mais moins efficace qu'une seule
SequentialScan sur un index composite de ["b" ASC, "a" ASC].
• SeekingScan
| constraints: /
|----(-∞..+∞)
|----[1L]
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, quantity ASC, __key__ ASC]
| keys: [user ASC, quantity ASC, __key__ ASC]
| properties: Selection { user }
| records returned: 1
| records scanned: 1
SequentialScan
Représente une analyse d'une plage statique et séquentielle de lignes dans le stockage qui peut être effectuée en une seule opération de lecture.
La key ordering length fait référence au nombre de clés qui doivent être conservées et renvoyées dans l'ordre des clés d'origine. Pour un schéma de [k1, k2, k3], une longueur d'ordre de clé de 0 signifie que l'analyse peut renvoyer les résultats dans n'importe quel ordre, 1 signifie que l'ordre est défini par k1, mais les lignes avec la même valeur k1 peuvent être dans n'importe quel ordre, et 3 renvoie les documents dans l'ordre de tri exact.
• SequentialScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| key ordering length: 3
| keys: [user ASC, date_placed ASC, __key__ ASC]
| limit: 10
| properties: Selection { a }
| ranges: /
| records returned: 1
| records scanned: 1
UniqueScan
Représente une analyse d'une plage statique et séquentielle de lignes dans le stockage avec déduplication en mémoire des lignes.
• UniqueScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| keys: [user ASC, date_placed ASC, __key__ ASC]
| properties: Selection { a }
| ranges: /
|----(-∞..+∞)
| records returned: 1
| records scanned: 1
IndexSeek
Représente une analyse dynamique dans laquelle les lignes renvoyées peuvent être paramétrées par des données d'exécution et ne pas se trouver dans une seule plage séquentielle de l'index, et plusieurs analyses distinctes peuvent être effectuées pour satisfaire la requête.
Par exemple, une requête où user est égal à $user_id et date_placed est égal à
"2025-08-10" s'exécutant sur un index de ["user" ASC, "date_placed" ASC], utiliserait
la valeur de la variable $user_id lors de l'exécution et la contrainte "2025-08-10"
sur date_placed pour limiter les plages d'analyse.
• IndexSeek
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| fields: [$user_1 ASC, $date_placed_1 ASC, $rid ASC]
| key: $key_1
| filter: $eq($user_1, $user_id) AND $eq($date_placed_1, "2025-08-10")
| records returned: 1
| records scanned: 1
Récupérer
Joint l'identifiant de la ligne fournie au contenu réel de la ligne à partir du stockage principal. Fetch est obligatoire si un nœud parent (ou le résultat final de la requête) nécessite un sous-ensemble de champs des documents.
• Fetch
| order: PRESERVE_INPUT_ORDER
| peak memory usage: 4.00 KiB (4,096 B)
| properties: *
| records returned: 1
TableScan
Analyse complète et non ordonnée d'une collection. Utilisé lorsqu'une requête est exécutée sans index associé.
L'ordre peut être STABLE ou UNDEFINED, STABLE indiquant un ordre déterministe.
• TableScan
| order: STABLE
| properties: *
| records returned: 1
| records scanned: 1
| source: (default)#/**/collection
Appliquer
Effectue une jointure entre deux ensembles de données (input et map) en itérant sur chaque ligne de l'input et, pour chaque ligne, en analysant et en renvoyant les résultats du côté map.
Le join_type indique le type de jointure. Par exemple, LEFT_OUTER signifie que toutes les lignes de l'input sont incluses au moins une fois dans la sortie.
Si une ligne input ne trouve aucun résultat du côté map, elle sera toujours incluse, avec des valeurs null pour les colonnes du côté map.
• Apply
| join_type: LEFT_OUTER
|
└── • input tree
| ...
└── • map tree
...
HashAggregate
Implémentation basée sur le hachage des opérations d'agrégation. Nécessite la matérialisation du groupe complet en mémoire avant de renvoyer le résultat et ne doit pas dépasser la limite de mémoire de la requête.
• HashAggregate
| aggregations: [sum($b_1) AS total]
| groups: [$a_1]
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 0
StreamAggregate
Nœud d'agrégation spécialisé qui ne conserve l'état que d'un seul groupe à la fois, ce qui réduit l'utilisation maximale de la mémoire. Utilisé lorsque le nœud enfant sous-jacent renvoie des groupes de manière séquentielle. Par exemple, lors du regroupement par valeurs distinctes d'un champ tout en utilisant un index sur ce champ.
• StreamAggregate
| keys: [foo ASC, bar ASC]
| properties: Selection { baz }
| aggregations: [$sum($foo_1) AS baz]
MajorSort
Effectue une opération de tri sur un ensemble fixe de propriétés. Matérialise tous les enregistrements en mémoire à la fois et renvoie les valeurs triées dans l’ordre. La taille de l’ensemble de tri est limitée par la limite de mémoire de la requête.
Lorsqu'une limite ultérieure est fournie, un algorithme de tri top-k est utilisé pour réduire l'utilisation de la mémoire. Il permet d'effectuer des tris sur un ensemble d'enregistrements arbitrairement volumineux, à condition que la mémoire utilisée pour stocker les éléments k considérés ne dépasse pas la limite.
• MajorSort
| fields: [a ASC, b DESC]
| limit: 10
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 1
Concat
Concatène les résultats de plusieurs nœuds enfants et renvoie le résultat au nœud parent. Ce nœud ne déduplique pas les résultats qui apparaissent dans plusieurs enfants, et l'ordre des résultats renvoyés n'est pas déterministe.
• Concat
├── • Fetch
...
├── • Fetch
Calcul
Évalue un ensemble d'expressions, en attribuant les résultats à un ensemble de variables.
• Compute
| $user_1: user
| $full_name_1: str_concat($first_name_1, " ", $last_name_1)
| $address_1: UNSET
| records returned: 1
Filtre
Renvoie de manière sélective les lignes si et seulement si elles correspondent à l'expression fournie.
• Filter
| expression: $eq(foo, "bar")
| records returned: 1
RecordCount
Compte le nombre de lignes produites par le nœud enfant et émet le nombre actuel dans la variable spécifiée dans l'attribut count.
• RecordCount
| count: $row_number_1
| records returned: 1
Valeurs
Produit une séquence de valeurs littérales sur lesquelles travailler. Utilisé principalement lorsqu'une liste définie de documents est fournie en entrée d'une requête.
• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]
Unnest
Annule l'imbrication de la valeur produite par le nœud enfant.
• Unnest
| expression: foo AS unnested_foo
Limite
Limite le nombre de lignes renvoyées au nœud parent.
• Limit
| limit: 10
| records returned: 1
Décalage (offset)
Ignore un nombre défini de lignes produites par le nœud enfant.
• Offset
| offset: 10
| records returned: 1