Auf dieser Seite wird die Ausgabe einer Abfrage erläutert, die mit Query Explain ausgeführt wurde. Informationen zum Ausführen einer Abfrage mit Query Explain finden Sie unter Abfrageausführung mit Query Explain analysieren.
Allgemeine Konzepte
Die folgenden gängigen Konzepte und Begriffe werden im gesamten Ausführungsbaum verwendet.
Zeilen und Datensätze
Die Begriffe Zeile und Eintrag werden allgemein für ein Dokument oder einen Indexeintrag verwendet.
Variablen
$ bezeichnet eine Variable, die im Ausführungsbaum erstellt oder referenziert wird. Beispiel: $foo_1 Diese Variablen werden normalerweise verwendet, um auf den Inhalt eines Dokuments oder den Wert eines Ausdrucks zu verweisen, der während der Ausführung einer Abfrage ausgewertet wird.
Die folgenden internen Variablen können in den Ausführungsknoten angezeigt werden:
$__key__: Der Schlüssel ist eine interne Kennung für ein Dokument. Dies ist eine absolute, eindeutige Kennung mit dem Projekt, der Datenbank und dem vollständigen Pfad des Dokuments.$__id__: Die ID ist eine eindeutige Kennung für ein Dokument innerhalb seiner Sammlung. Sie ist innerhalb einer einzelnen Sammlung eindeutig.$rid: Die Zeilen-ID ist eine interne Kennung für ein Dokument im Speicher. Diese ist innerhalb einer einzelnen Sammlung eindeutig.
Betrachten Sie ein Beispiel, in dem ein Compute-Knoten verwendet wird, um die __id__ aus dem Dokument __key__ zu berechnen:
Compute
| $__id__1: _id($__key__)
| records returned: 1
Einschränkungen und Bereiche
Einige Scan-Knoten verwenden die Attribute constraints und ranges, um den Bereich der gescannten Werte zu beschreiben. Diese Attribute verwenden ein Bereichsbaumformat, das eine Liste von Werten enthält. Diese Werte entsprechen der sortierten Liste der Schlüssel, die in der Indexdefinition angezeigt werden. Der erste Bereich, der im Baum angezeigt wird, hier (1..5], entspricht beispielsweise den Einschränkungen für den ersten Schlüssel, hier a, in der sortierten Liste der Schlüssel:
| index: type=CollectionGroupIndex, id=CICAgOjXh#EK, keys=[a ASC, b ASC, __key__ ASC]
| constraints: /
|----(1..5]
|----[1L]
Jede Einrückungsebene gibt die Einschränkung an, die für den nächsten Schlüssel in der Liste gilt. Eckige Klammern stehen für einen eingeschlossenen Bereich, runde Klammern für einen ausgeschlossenen Bereich. In diesem Fall wird die Einschränkung in 1 < "a" <= 5 und "b" = 1 übersetzt.
Im folgenden Beispiel mit mehreren Zweigen für a entspricht die Einschränkung 1 < a <= 5 OR a = 10:
| constraints: /
|----(1L, 5L]
|----[10L]
Schlüsselvariablen
In einigen Scan-Knoten (z. B. SequentialScan) gibt es sowohl eine Liste von Schlüsseln als Teil des Attributs index als auch ein separates Attribut keys im Knoten Scan. Das Attribut keys im Knoten Scan gibt den Variablennamen jedes Schlüssels in der Indexdefinition in der richtigen Reihenfolge an. Mit den Variablen kann auf die Laufzeitwerte des gescannten Felds weiter oben im Ausführungsbaum verwiesen werden.
Im folgenden Beispiel wird der Wert des Felds user für das aktuelle Dokument der Variablen $user_1 und der Wert von date_placed der Variablen $date_placed_1 zugeordnet.
index: type=CollectionGroupIndex, id=CICAgOjXh4EK, keys=[user ASC, date_placed ASC, __key__ ASC]
keys: [user ASC, date_placed ASC, __key__ ASC]
Ausführungsknoten
Ein Abfrageausführungsbaum kann die folgenden Knoten enthalten.
SeekingScan
Stellt einen dynamischen Scan dar, bei dem die zurückgegebenen Zeilen möglicherweise nicht in einem einzelnen sequenziellen Bereich des Index liegen und mehrere unterschiedliche Scans durchgeführt werden müssen, um die Abfrage zu erfüllen.
Beispiel: Bei einer Abfrage, in der a vorhanden ist und b gleich 1 ist, die auf einem Index von ["a" ASC, "b" ASC] ausgeführt wird, müsste für jeden eindeutigen Wert von a ein separater, potenziell nicht sequenzieller Bereich gescannt und zurückgegeben werden.
Dies ist effizienter als ein vollständiger TableScan, aber weniger effizient als ein einzelner SequentialScan für einen zusammengesetzten Index von ["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
Stellt einen Scan eines statischen, sequenziellen Bereichs von Zeilen im Speicher dar, der in einem einzigen Lesevorgang ausgeführt werden kann.
key ordering length bezieht sich auf die Anzahl der Schlüssel, die beibehalten und in der ursprünglichen Schlüsselreihenfolge zurückgegeben werden müssen. Bei einem Schema von [k1, k2, k3] bedeutet eine Schlüsselsortierungslänge von 0, dass der Scan in beliebiger Reihenfolge zurückgegeben werden kann. 1 bedeutet, dass nach k1 sortiert wird, aber Zeilen mit demselben k1-Wert können in beliebiger Reihenfolge zurückgegeben werden. 3 gibt Dokumente in genau sortierter Reihenfolge zurück.
• 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
Stellt einen Scan eines statischen, sequenziellen Bereichs von Zeilen im Speicher mit In-Memory-Deduplizierung von Zeilen dar.
• 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
Stellt einen dynamischen Scan dar, bei dem die zurückgegebenen Zeilen durch Laufzeitdaten parametrisiert werden können und möglicherweise nicht in einem einzelnen sequenziellen Bereich des Index liegen. Außerdem können mehrere unterschiedliche Scans durchgeführt werden, um die Abfrage zu erfüllen.
Beispiel: Eine Abfrage, bei der user gleich $user_id und date_placed gleich "2025-08-10" ist und die für einen Index von ["user" ASC, "date_placed" ASC] ausgeführt wird, verwendet den Wert der Variable $user_id zur Laufzeit und die Einschränkung "2025-08-10" für date_placed, um die Scanbereiche einzuschränken.
• 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
Abrufen
Verknüpft die Kennung der angegebenen Zeile mit dem tatsächlichen Zeileninhalt aus dem primären Speicher. Fetch ist erforderlich, wenn ein übergeordneter Knoten (oder das endgültige Abfrageergebnis) eine Teilmenge von Feldern aus den Dokumenten erfordert.
• Fetch
| order: PRESERVE_INPUT_ORDER
| peak memory usage: 4.00 KiB (4,096 B)
| properties: *
| records returned: 1
TableScan
Ein vollständiger, unsortierter Scan einer Sammlung. Wird verwendet, wenn eine Abfrage ohne zugehörigen Index ausgeführt wird.
Die Reihenfolge kann entweder STABLE oder UNDEFINED sein, wobei STABLE eine deterministische Reihenfolge angibt.
• TableScan
| order: STABLE
| properties: *
| records returned: 1
| records scanned: 1
| source: (default)#/**/collection
Übernehmen
Führt einen Join zwischen zwei Datensätzen (input und map) durch. Dazu wird jede Zeile von input durchlaufen und für jede Zeile werden Ergebnisse von der map-Seite gescannt und zurückgegeben.
join_type gibt den Typ des Joins an. LEFT_OUTER bedeutet beispielsweise, dass alle Zeilen aus input mindestens einmal in der Ausgabe enthalten sind.
Wenn für eine input-Zeile keine Ergebnisse auf der map-Seite gefunden werden, wird sie trotzdem mit null-Werten für die Spalten auf der map-Seite einbezogen.
• Apply
| join_type: LEFT_OUTER
|
└── • input tree
| ...
└── • map tree
...
HashAggregate
Hash-basierte Implementierung von Aggregationsvorgängen. Erfordert die Materialisierung der gesamten Gruppe im Arbeitsspeicher, bevor das Ergebnis zurückgegeben wird, und darf das Abfragespeicherlimit nicht überschreiten.
• HashAggregate
| aggregations: [sum($b_1) AS total]
| groups: [$a_1]
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 0
StreamAggregate
Spezialisierter Aggregatknoten, der den Status jeweils nur für eine einzelne Gruppe beibehält, wodurch die maximale Arbeitsspeichernutzung reduziert wird. Wird verwendet, wenn der zugrunde liegende untergeordnete Knoten Gruppen nacheinander zurückgibt. Beispiel: Wenn Sie nach eindeutigen Werten eines Felds gruppieren und einen Index für dieses Feld verwenden.
• StreamAggregate
| keys: [foo ASC, bar ASC]
| properties: Selection { baz }
| aggregations: [$sum($foo_1) AS baz]
MajorSort
Führt einen Sortiervorgang für eine feste Gruppe von Attributen aus. Materialisiert alle Datensätze gleichzeitig im Arbeitsspeicher und gibt die sortierten Werte in der richtigen Reihenfolge zurück. Die Größe des Sortiersatzes ist durch das Arbeitsspeicherlimit für Abfragen begrenzt.
Wenn ein nachfolgendes Limit angegeben wird, wird ein Top-K-Sortieralgorithmus verwendet, um die Arbeitsspeichernutzung zu reduzieren. Damit können Sortierungen für eine beliebig große Anzahl von Datensätzen durchgeführt werden, solange der durch das Speichern der k berücksichtigten Elemente verwendete Arbeitsspeicher das Limit nicht überschreitet.
• MajorSort
| fields: [a ASC, b DESC]
| limit: 10
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 1
Concat
Verkettet die Ergebnisse mehrerer untergeordneter Knoten und gibt das Ergebnis an den übergeordneten Knoten zurück. Dieser Knoten dedupliziert keine Ergebnisse, die in mehreren untergeordneten Knoten vorkommen, und die Reihenfolge der zurückgegebenen Ergebnisse ist nicht deterministisch.
• Concat
├── • Fetch
...
├── • Fetch
Compute
Wertet eine Reihe von Ausdrücken aus und weist die Ergebnisse einer Reihe von Variablen zu.
• Compute
| $user_1: user
| $full_name_1: str_concat($first_name_1, " ", $last_name_1)
| $address_1: UNSET
| records returned: 1
Filter
Gibt Zeilen nur dann zurück, wenn sie mit dem angegebenen Ausdruck übereinstimmen.
• Filter
| expression: $eq(foo, "bar")
| records returned: 1
RecordCount
Zählt die Anzahl der vom untergeordneten Knoten erzeugten Zeilen und gibt die aktuelle Anzahl an die im Attribut count angegebene Variable aus.
• RecordCount
| count: $row_number_1
| records returned: 1
Werte
Erzeugt eine Sequenz von Literalwerten, die verarbeitet werden sollen. Wird hauptsächlich verwendet, wenn eine festgelegte Liste von Dokumenten als Eingabe für eine Abfrage bereitgestellt wird.
• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]
Verschachtelung aufheben
Hebt die Verschachtelung des vom untergeordneten Knoten erzeugten Werts auf.
• Unnest
| expression: foo AS unnested_foo
Limit
Begrenzt die Anzahl der Zeilen, die an den übergeordneten Knoten zurückgegeben werden.
• Limit
| limit: 10
| records returned: 1
Offset
Überspringt eine festgelegte Anzahl von Zeilen, die vom untergeordneten Knoten erzeugt werden.
• Offset
| offset: 10
| records returned: 1