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
$
indica una variabile creata o
a cui viene fatto riferimento nell'albero di esecuzione. Ad esempio: $foo_1
. 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.
Nei nodi di esecuzione possono essere visualizzate le seguenti variabili interne:
$__key__
: la chiave è un identificatore interno per 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.
Considera un esempio in cui un nodo Compute
viene utilizzato per calcolare
__id__
dal documento __key__
:
Compute
| $__id__1: _id($__key__)
| 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 che si applica 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
corrisponde alla variabile $user_1
e il valore di date_placed
a $date_placed_1
.
index: type=CollectionGroupIndex, id=CICAgOjXh4EK, keys=[user ASC, date_placed ASC, __key__ ASC]
keys: [user ASC, date_placed ASC, __key__ 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: [user ASC, quantity 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 per
k1, ma le righe con lo stesso valore k1 possono essere restituite in qualsiasi ordine, 3 restituisce i documenti
nell'ordine esatto.
• 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
Rappresenta una scansione di un intervallo statico e sequenziale di righe 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: [user ASC, date_placed 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
primario. 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
LookupById
Esegue un'unione cercando i documenti in una raccolta esterna in base al loro ID. Gli ID da cercare provengono da un campo nei documenti di input. I risultati della ricerca vengono aggiunti come nuovo campo ai documenti di input.
• LookupById
| local_field: $localField_1
| foreign_datasource: (default)#/**/foreign
| output: $output_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($b_1) AS total]
| groups: [$a_1]
| 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_1) 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à, gli ordinamenti possono essere eseguiti su un insieme di record arbitrariamente grande, a condizione che la memoria utilizzata per memorizzare 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
Computing
Valuta un insieme di espressioni, assegnando i risultati a un insieme di variabili.
• Compute
| $user_1: user
| $full_name_1: str_concat($first_name_1, " ", $last_name_1)
| $address_1: UNSET
| 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}]
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