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