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 allgemeinen Konzepte und Begriffe werden im gesamten Ausführungsbaum verwendet.
Zeilen und Datensätze
Die Begriffe Zeile und Datensatz werden allgemein für einen Dokument- oder Indexeintrag verwendet.
Variablen
$ kennzeichnet eine Variable, die im Ausführungsbaum erstellt oder
referenziert wird. Beispiel: $foo_1. Diese Variablen werden in der Regel 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 vorkommen:
$__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 in seiner Sammlung. Sie ist innerhalb einer einzelnen Sammlung eindeutig.$rid– Die Zeilen-ID ist eine interne Kennung für ein Dokument im Speicher. Sie ist innerhalb einer einzelnen Sammlung eindeutig.
Beispiel: Ein Compute-Knoten wird verwendet, um die __id__ aus dem Dokument __key__ zu berechnen:
Compute
| $__id__1: _id($__key__)
| records returned: 1
Einschränkungen und Bereiche
Einige Scanknoten 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 von Schlüsseln, die in der Indexdefinition enthalten sind. Der erste Bereich im Baum, 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 auf den nächsten Schlüssel in der Liste angewendet wird. 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 Scanknoten (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. Die Variablen können verwendet werden, um weiter oben im Ausführungsbaum auf die Laufzeitwerte des gescannten Felds zu verweisen.
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 ausgeführt werden müssen, um die Abfrage zu erfüllen.
Bei einer Abfrage, bei der a vorhanden ist und b gleich 1 ist, und die auf einem
Index von ["a" ASC, "b" ASC] ausgeführt wird, muss beispielsweise für jeden unterschiedlichen Wert von a ein separater,
möglicherweise 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 einzelnen Lesevorgang ausgeführt werden kann.
Die key ordering length bezieht sich auf die Anzahl der Schlüssel, die in der ursprünglichen Schlüsselreihenfolge beibehalten und zurückgegeben werden müssen. Bei einem Schema von [k1, k2, k3] bedeutet eine Länge der Schlüsselreihenfolge von 0, dass der Scan in beliebiger Reihenfolge zurückgegeben werden kann. Bei 1 wird nach k1 sortiert, aber Zeilen mit demselben k1-Wert können in beliebiger Reihenfolge zurückgegeben werden. Bei 3 werden Dokumente in genau sortierter Reihenfolge zurückgegeben.
• 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 möglicherweise durch Laufzeitdaten parametrisiert werden und nicht in einem einzelnen sequenziellen Bereich des Index liegen. Es können mehrere unterschiedliche Scans ausgeführt werden, um die Abfrage zu erfüllen.
Bei einer Abfrage, bei der user gleich $user_id und date_placed gleich
"2025-08-10" ist und die auf einem Index von ["user" ASC, "date_placed" ASC] ausgeführt wird, wird
der Wert der Variablen $user_id zur Laufzeit und die "2025-08-10"
Einschränkung für date_placed verwendet, 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
Führt einen Back-Join der ID der angegebenen Zeile mit dem tatsächlichen Zeileninhalt aus dem primären Speicher aus. Fetch ist erforderlich, wenn ein übergeordneter Knoten (oder das endgültige Abfrageergebnis) eine Teilmenge der Felder aus den Dokumenten benötigt.
• 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) aus, indem jede Zeile von input durchlaufen und für jede Zeile Ergebnisse von der map-Seite gescannt und zurückgegeben werden.
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 von der map-Seite gefunden werden, ist sie trotzdem enthalten, mit null-Werten für die Spalten von der map-Seite.
• Apply
| join_type: LEFT_OUTER
|
└── • input tree
| ...
└── • map tree
...
HashAggregate
Hash-basierte Implementierung von Aggregatvorgängen. Erfordert die Materialisierung der gesamten Gruppe im Arbeitsspeicher, bevor das Ergebnis zurückgegeben wird, und darf das Limit für den Abfragespeicher 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 Gruppe verwaltet, wodurch die maximale Arbeitsspeichernutzung reduziert wird. Wird verwendet, wenn der zugrunde liegende untergeordnete Knoten Gruppen sequenziell zurückgibt. Beispiel: Gruppieren nach unterschiedlichen Werten eines Felds bei Verwendung eines Index für dieses Feld.
• StreamAggregate
| keys: [foo ASC, bar ASC]
| properties: Selection { baz }
| aggregations: [$sum($foo_1) AS baz]
MajorSort
Führt einen Sortiervorgang für einen festen Satz 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 Sortier satzes ist durch das Limit für den Abfragespeicher 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 ausgeführt werden, solange der Arbeitsspeicher, der zum Speichern der k berücksichtigten Elemente verwendet wird, 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 Zeilen, die vom untergeordneten Knoten erzeugt wurden, und gibt die aktuelle Anzahl an die Variable aus, die im Attribut count angegeben ist.
• RecordCount
| count: $row_number_1
| records returned: 1
Werte
Erzeugt eine Sequenz von Literalwerten, mit denen gearbeitet werden kann. 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 bestimmte Anzahl von Zeilen, die vom untergeordneten Knoten erzeugt wurden.
• Offset
| offset: 10
| records returned: 1