Referenz zur Abfrageausführung
Auf dieser Seite wird die Ausgabe einer mit „Query Explain“ ausgeführten Abfrage erläutert. Informationen zum Ausführen einer Abfrage mit Query Explain finden Sie unter Abfrageausführung mit Query Explain analysieren.Häufig verwendete Konzepte
Im gesamten Ausführungsbaum werden die folgenden allgemeinen Konzepte und Begriffe verwendet.
Zeilen und Datensätze
Die Begriffe Zeile und Datensatz werden allgemein für ein Dokument oder einen Indexeintrag verwendet.
Variablen
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 innerhalb der Sammlung. Sie ist innerhalb einer einzelnen Sammlung eindeutig.__$0__…__$N__
– das sind kontextspezifische Variablen, die im Ausführungsbaum erstellt oder auf die dort verwiesen wird. 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.
Betrachten Sie ein Beispiel, in dem ein Extend-Knoten verwendet wird, um die __id__
aus dem Dokument __key__
zu extrahieren:
Extend
| expressions: [_id(__key__) AS __id__]
| 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 enthalten sind. 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 für den nächsten Schlüssel in der Liste an. 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. 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 __$6__
und der Wert von date_placed
der Variablen __$7__
zugeordnet.
index: type=CollectionGroupIndex, id=CICAgOjXh4EK, keys=[user ASC, date_placed ASC, __path__ ASC]
keys: [__$6__ ASC, __$7__ ASC, __path__ ASC]
Ausführungsknoten
Ein Baum für die Ausführung von Abfragen 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 separate Scans ausgeführt werden müssen, um die Abfrage zu erfüllen.
Bei einer Abfrage, in der a
vorhanden ist und b
gleich 1 ist, und die auf einem Index von ["a" ASC, "b" ASC]
basiert, muss für jeden eindeutigen Wert von a
ein separater, möglicherweise nicht sequenzieller Bereich gescannt und zurückgegeben werden.
Das 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: [__$1__ ASC, __$2__ 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.
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üsselreihenfolgenlänge 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: [__$1__ ASC, __$2__ ASC, __key__ ASC]
| limit: 10
| properties: Selection { a }
| ranges: /
| records returned: 1
| records scanned: 1
UniqueScan
Stellt einen Scan eines statischen, sequenziellen Zeilenbereichs im Speicher mit In-Memory-Deduplizierung von Zeilen dar.
• UniqueScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| keys: [__$1__ ASC, __$2__ ASC, __key__ ASC]
| properties: Selection { a }
| ranges: /
|----(-∞..+∞)
| records returned: 1
| records scanned: 1
TableAccess
Führt die ID der angegebenen Zeile mit dem tatsächlichen Zeileninhalt aus dem primären Speicher zusammen. TableAccess
ist erforderlich, wenn für einen übergeordneten Knoten (oder das endgültige Abfrageergebnis) eine Teilmenge von Feldern aus den Dokumenten erforderlich ist.
• TableAccess
| order: PRESERVE_INPUT_ORDER
| peak memory usage: 4.00 KiB (4,096 B)
| properties: *
| records returned: 1
TableScan
Ein vollständiger, ungeordneter Scan einer Sammlung. Wird verwendet, wenn eine Abfrage ohne zugehörigen Index ausgeführt wird.
Die Reihenfolge kann entweder STABLE
oder UNDEFINED
sein. STABLE
steht für eine deterministische Reihenfolge.
• TableScan
| order: STABLE
| properties: *
| records returned: 1
| records scanned: 1
| source: (default)#/**/collection
HashAggregate
Hashbasierte Implementierung von Aggregatvorgängen. Erfordert die Materialisierung der gesamten Gruppe im Arbeitsspeicher, bevor das Ergebnis zurückgegeben wird, und darf das Speicherlimit für Abfragen nicht überschreiten.
• HashAggregate
| aggregations: [sum(__$0__) AS total]
| groups: [a]
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 0
StreamAggregate
Spezialisierter Aggregatknoten, der jeweils nur den Status für eine einzelne Gruppe verwaltet, wodurch die maximale Arbeitsspeichernutzung reduziert wird. Wird verwendet, wenn der zugrunde liegende untergeordnete Knoten Gruppen sequenziell zurückgibt. Das ist beispielsweise der Fall, wenn Sie nach eindeutigen Werten eines Felds gruppieren und gleichzeitig einen Index für dieses Feld verwenden.
• StreamAggregate
| keys: [foo ASC, bar ASC]
| properties: Selection { baz }
| aggregations: [$sum(foo) AS baz]
MajorSort
Führt einen Sortiervorgang für eine feste Gruppe von Attributen aus. Alle Datensätze werden gleichzeitig im Arbeitsspeicher materialisiert und die sortierten Werte werden in der richtigen Reihenfolge zurückgegeben. 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 Speichernutzung zu reduzieren. Damit können Sortierungen für eine beliebig große Menge von Datensätzen durchgefü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. Bei diesem Knoten werden Ergebnisse, die in mehreren untergeordneten Elementen vorkommen, nicht dedupliziert und die Reihenfolge der zurückgegebenen Ergebnisse ist nicht deterministisch.
• Concat
├── • TableAccess
...
├── • TableAccess
Einschränken
Projiziert eine Reihe von Attributen, die an den übergeordneten Knoten übergeben werden sollen. Reduziert die Speichernutzung, da die Weitergabe nicht verwendeter Felder verhindert wird, sobald sie für den Rest der Abfrage irrelevant sind.
• Restrict
| expressions: [foo AS foo, bar AS bar]
| records returned: 0
Verlängern
Fügt jeder Zeile im Ergebnis eine Reihe von Feldern hinzu. Wird verwendet, wenn Felder einem Dokument hinzugefügt werden, und als Zwischenknoten zur Unterstützung komplexerer Vorgänge.
• Extend
| expressions: ["bar" AS foo]
| records returned: 1
Filter
Gibt Zeilen nur dann zurück, wenn sie dem angegebenen Ausdruck entsprechen.
• Filter
| expression: $eq(foo, "bar")
| records returned: 1
Werte
Erstellt eine Folge von Literalwerten, mit denen gearbeitet werden kann. Wird hauptsächlich verwendet, wenn eine Liste von Dokumenten als Eingabe für eine Abfrage bereitgestellt wird.
• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]
ReplaceWith
Ersetzt die Felder der Zeilen, die vom untergeordneten Knoten generiert werden, durch die Felder aus dem angegebenen map
-Ausdruck.
• ReplaceWith
| map: map("full_name", str_concat(first_name, " ", last_name)), current_context())
| records returned: 1
Unnest
Hebt die Verschachtelung des vom untergeordneten Knoten erstellten Werts auf.
• Unnest
| expression: foo AS unnested_foo
Limit
Beschränkt 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 generiert werden.
• Offset
| offset: 10
| records returned: 1
Ablegen
Entfernt einen bestimmten Satz von Feldern aus den Ergebnissen, die vom untergeordneten Knoten generiert werden.
• Drop
| fields to drop: [__key__]
| records returned: 1