Riferimento all'esecuzione delle query
Questa pagina spiega l'output di una query eseguita con Query Explain. Per scoprire come eseguire una query con Query Explain, consulta Analizzare l'esecuzione delle query con Query Explain.Common Concepts
I seguenti concetti e termini comuni vengono utilizzati in tutto l'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 di 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 per un documento all'interno della raccolta. È univoco all'interno di una singola raccolta.__$0__…__$N__
: si tratta di variabili specifiche per il contesto 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.
Considera un esempio in cui un nodo di estensione viene utilizzato 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 scansionati. Questi attributi utilizzano un formato ad albero di intervalli che
contiene un elenco di valori. Questi valori corrispondono all'elenco ordinato di chiavi
che vengono visualizzate 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 inclusivo, mentre le parentesi tonde rappresentano un intervallo esclusivo. In questo caso, il vincolo 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 chiave
In alcuni nodi di scansione (ad esempio SequentialScan
), sono presenti 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 scansionato 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 delle 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 per soddisfare la query.
Ad esempio, una query in cui a
esiste e b
è uguale a 1 che opera su un
indice di ["a" ASC, "b" ASC]
, dovrebbe scansionare e restituire un intervallo separato,
potenzialmente non sequenziale per ogni valore distinto di a
.
È più efficiente di un TableScan
completo, ma meno efficiente di un singolo
SequentialScan
su 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 statico e sequenziale di righe nello spazio di archiviazione che può essere eseguita in una singola operazione di lettura.
key ordering length
si riferisce al numero di chiavi che devono essere conservate
e restituite nell'ordine originale. Per uno schema di [k1, k2, k3]
, una lunghezza
di 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 restituite 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 statico e sequenziale nello spazio di archiviazione con la deduplicazione 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 back-join dell'identificatore della riga fornita ai contenuti effettivi della riga dallo spazio di archiviazione
principale. TableAccess
è obbligatorio se un nodo principale (o il risultato della query finale) 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. Utilizzato quando una query viene eseguita senza un indice associato.
L'ordine può essere STABLE
o UNDEFINED
, dove STABLE
indica un
ordinamento deterministico.
• TableScan
| order: STABLE
| properties: *
| records returned: 1
| records scanned: 1
| source: (default)#/**/collection
HashAggregate
Implementazione basata su hash delle operazioni di aggregazione. Richiede la materializzazione dell'intero gruppo in memoria prima di restituire il risultato e non deve superare il 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 di aggregazione specializzato che mantiene lo stato di un solo gruppo alla volta, riducendo l'utilizzo massimo della memoria. Utilizzato quando il nodo secondario sottostante restituirà i gruppi in sequenza. Ad esempio, quando raggruppi in base ai valori distinti di un campo mentre utilizzi 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. La dimensione dell'insieme di ordinamento è limitata 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 questa funzionalità, è possibile eseguire ordinamenti su un insieme di record arbitrariamente grande, a condizione che la memoria utilizzata per archiviare i k elementi considerati 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 secondari e restituisce il risultato al nodo principale. Questo nodo non deduplica i risultati visualizzati in più figli e l'ordine dei risultati restituiti non è deterministico.
• Concat
├── • TableAccess
...
├── • TableAccess
Limita
Proietta un insieme di proprietà da passare al nodo principale. Riduce l'utilizzo della memoria impedendo la propagazione dei campi inutilizzati non appena diventano irrilevanti 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. Utilizzato quando si aggiungono campi a un documento e come nodo intermedio per supportare operazioni più complesse.
• Extend
| expressions: ["bar" AS foo]
| records returned: 1
Filtro
Restituisce selettivamente 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. Utilizzato principalmente quando un insieme di documenti viene fornito come input a una query.
• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]
ReplaceWith
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
Separa 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
Ignora un numero prestabilito di righe prodotte dal nodo secondario.
• Offset
| offset: 10
| records returned: 1
Elimina
Elimina un insieme specifico di campi dai risultati prodotti dal nodo secondario.
• Drop
| fields to drop: [__key__]
| records returned: 1