Riferimento all'esecuzione della query
Questa pagina spiega l'output di una query eseguita con Query Explain. Per scoprire come eseguire una query con Query Explain, consulta Analisi dell'esecuzione delle query con Query Explain.Concetti comuni
I seguenti concetti e termini comuni vengono utilizzati nell'intero albero di esecuzione.
Righe e record
I termini riga e record vengono utilizzati per fare riferimento in modo generico a un documento o a una voce dell'indice.
Variabili
Nei nodi di esecuzione possono essere visualizzate le seguenti variabili interne:
__key__
: la chiave è un identificatore interno di un documento. Si tratta di un identificatore assoluto e univoco con il progetto, il database e il percorso completo del documento.__id__
: l'ID è un identificatore univoco di un documento all'interno della relativa raccolta. Deve essere univoco all'interno di una singola raccolta.__$0__…__$N__
: si tratta di variabili specifiche del contesto che vengono create o a cui viene fatto riferimento nell'albero di esecuzione. Queste variabili vengono in genere utilizzate per fare riferimento ai contenuti di un documento o al valore di un'espressione valutata durante l'esecuzione di una query.
Prendi in considerazione un esempio in cui viene utilizzato un nodo di estensione per estrarre__id__
dal documento __key__
:
Extend
| expressions: [_id(__key__) AS __id__]
| records returned: 1
Vincoli e intervalli
Alcuni nodi di scansione utilizzano gli attributi constraints
e ranges
per descrivere l'intervallo
di valori sottoposti a scansione. Questi attributi utilizzano un formato ad albero di intervalli che contiene un elenco di valori. Questi valori corrispondono all'elenco ordinato di chiavi
che appaiono nella definizione dell'indice. Ad esempio, il primo intervallo visualizzato
nell'albero, qui (1..5]
, corrisponde ai vincoli della prima chiave,
qui a
, nell'elenco ordinato delle chiavi:
| index: type=CollectionGroupIndex, id=CICAgOjXh#EK, keys=[a ASC, b ASC, __key__ ASC]
| constraints: /
|----(1..5]
|----[1L]
Ogni livello di rientro indica il vincolo applicato alla chiave successiva nell'elenco. Le parentesi quadre rappresentano un intervallo incluso, mentre le parentesi tonde rappresentano un
intervallo esclusivo. In questo caso, la limitazione si traduce in 1 < "a" <= 5
e
"b" = 1
.
Nel seguente esempio con più rami per a
,
il vincolo corrisponde a 1 < a <= 5 OR a = 10
:
| constraints: /
|----(1L, 5L]
|----[10L]
Variabili principali
In alcuni nodi di scansione (ad esempio SequentialScan
), è presente sia un elenco di chiavi nell'ambito dell'attributo index
sia un attributo keys
separato nel nodo Scan
. L'attributo keys
nel nodo Scan
indica il nome della variabile di ogni chiave nella definizione dell'indice, in ordine. Le variabili possono essere utilizzate per fare riferimento ai valori di runtime del campo sottoposto a scansione più in alto nell'albero di esecuzione.
Nell'esempio seguente, il valore del campo user
per il documento corrente viene mappato alla variabile __$6__
e il valore di date_placed
a __$7__
.
index: type=CollectionGroupIndex, id=CICAgOjXh4EK, keys=[user ASC, date_placed ASC, __path__ ASC]
keys: [__$6__ ASC, __$7__ ASC, __path__ ASC]
Nodi di esecuzione
Un albero di esecuzione di query può contenere i seguenti nodi.
SeekingScan
Rappresenta una scansione dinamica in cui le righe restituite potrebbero non trovarsi in un singolo intervallo sequenziale dell'indice e devono essere eseguite più scansioni distinte persoddisfare la query.
Ad esempio, una query in cui esiste a
e b
è uguale a 1 che utilizza un
indice di ["a" ASC, "b" ASC]
, deve eseguire la scansione e restituire un
intervallo separato, potenzialmente non sequenziale, per ogni valore distinto di a
.
Questo è più efficiente di un TableScan
completo, ma meno di un singolo
SequentialScan
in un indice composito di ["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
Rappresenta una scansione di un intervallo di righe statiche e sequenziali nello spazio di archiviazione che può essere eseguita in un'unica operazione di lettura.
key ordering length
si riferisce al numero di chiavi che devono essere conservate
e restituite nell'ordine originale delle chiavi. Per uno schema [k1, k2, k3]
, una lunghezza dell'ordinamento delle chiavi pari a 0 indica che la scansione può restituire i risultati in qualsiasi ordine, 1 indica l'ordinamento in base a k1, ma le righe con lo stesso valore k1 possono essere in qualsiasi ordine, 3 restituisce i documenti in ordine esatto.
• 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
Rappresenta una scansione di un intervallo di righe statiche e sequenziali nello spazio di archiviazione con la deduplica in memoria delle righe.
• 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
Esegue il join inverso dell'identificatore della riga fornita con i contenuti effettivi della riga dall'archiviazione principale. TableAccess
è obbligatorio se un nodo principale (o il risultato finale della query) richiede un sottoinsieme di campi dei documenti.
• TableAccess
| order: PRESERVE_INPUT_ORDER
| peak memory usage: 4.00 KiB (4,096 B)
| properties: *
| records returned: 1
TableScan
Una scansione completa e non ordinata di una raccolta. Viene utilizzato quando viene eseguita una query senza un indice associato.
L'ordine può essere STABLE
o UNDEFINED
, dove STABLE
indica un ordine
deterministico.
• TableScan
| order: STABLE
| properties: *
| records returned: 1
| records scanned: 1
| source: (default)#/**/collection
HashAggregate
Implementazione delle operazioni aggregate basata su hash. Richiede la materializzazione del gruppo completo in memoria prima di restituire il risultato e non deve superare il limite di memoria per le query.
• HashAggregate
| aggregations: [sum(__$0__) AS total]
| groups: [a]
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 0
StreamAggregate
Nodo aggregato specializzato che gestisce lo stato solo per un singolo gruppo alla volta, riducendo l'utilizzo massimo della memoria. Viene utilizzato quando il nodo secondario sottostante restituisce i gruppi in sequenza. Ad esempio, quando raggruppi in base a valori distinti di un campo utilizzando un indice su quel campo.
• StreamAggregate
| keys: [foo ASC, bar ASC]
| properties: Selection { baz }
| aggregations: [$sum(foo) AS baz]
MajorSort
Esegue un'operazione di ordinamento su un insieme fisso di proprietà. Materializza tutti i record in memoria contemporaneamente e restituisce i valori ordinati in ordine, le dimensioni dell'insieme di ordinamento sono limitate dal limite di memoria della query.
Quando viene fornito un limite successivo, viene utilizzato un algoritmo di ordinamento top-k per ridurre l'utilizzo della memoria. Con questo metodo, è possibile eseguire ordinamento su un insieme arbitrariamente grande di record, purché la memoria utilizzata per l'archiviazione degli elementi considerati k non superi il limite.
• MajorSort
| fields: [a ASC, b DESC]
| limit: 10
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 1
Concat
Concatena i risultati di più nodi figlio e restituisce il risultato al nodo padre. Questo nodo non deduplica i risultati visualizzati in più elementi secondari e l'ordine dei risultati restituiti non è deterministico.
• Concat
├── • TableAccess
...
├── • TableAccess
Limita
Progetta un insieme di proprietà da passare al nodo principale. Riduce l'utilizzo della memoria impedendo la propagazione dei campi inutilizzati non appena non sono più pertinenti per il resto della query.
• Restrict
| expressions: [foo AS foo, bar AS bar]
| records returned: 0
Estendi
Aggiunge un insieme di campi a ogni riga del set di risultati. Viene utilizzato per aggiungere campi a un documento e come nodo intermedio per supportare operazioni più complesse.
• Extend
| expressions: ["bar" AS foo]
| records returned: 1
Filtro
Restituisce in modo selettivo le righe se e solo se corrispondono all'espressione fornita.
• Filter
| expression: $eq(foo, "bar")
| records returned: 1
Valori
Produce una sequenza di valori letterali su cui lavorare. Viene utilizzato principalmente quando viene fornito un insieme di documenti come input per una query.
• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]
SostituisciCon
Sostituisce i campi delle righe prodotte dal nodo secondario con i campi dell'espressione map
fornita.
• ReplaceWith
| map: map("full_name", str_concat(first_name, " ", last_name)), current_context())
| records returned: 1
Unnest
Estrae il valore prodotto dal nodo secondario.
• Unnest
| expression: foo AS unnested_foo
Limite
Limita il numero di righe restituite al nodo principale.
• Limit
| limit: 10
| records returned: 1
Offset
Salta un numero predefinito di righe prodotte dal nodo figlio.
• Offset
| offset: 10
| records returned: 1
Rilascia
Elimina un insieme specificato di campi dai risultati prodotti dal nodo secondario.
• Drop
| fields to drop: [__key__]
| records returned: 1