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