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 Analizza l'esecuzione delle query con Query Explain.

Concetti comuni

I seguenti concetti e termini comuni vengono utilizzati nell'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, che viene 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 di un documento. Si tratta di un identificatore univoco assoluto con il progetto, il database e il percorso completo del documento.
  • $__id__: l'ID è un identificatore univoco di un documento all'interno della sua raccolta. Questo valore è univoco all'interno di una singola raccolta.
  • $rid: l'ID riga è un identificatore interno di un documento nello spazio di archiviazione. Questo valore è univoco all'interno di una singola raccolta.

Considera un esempio in cui viene utilizzato un nodo Compute 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 compaiono nella definizione dell'indice. Ad esempio, il primo intervallo che appare nell'albero, qui (1..5], corrisponde ai vincoli sulla prima chiave, qui a, nell'elenco ordinato di 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.

Nell'esempio seguente 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 (come SequentialScan), è presente sia un elenco di chiavi come parte 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 $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 unico 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. Questo approccio è più efficiente di un TableScan completo, ma meno efficiente di un singolo SequentialScan su un indice composto 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 un'unica 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 l'analisi può restituire i risultati in qualsiasi ordine, 1 indica l'ordinamento per k1, ma le righe con lo stesso valore k1 possono essere visualizzate 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 deduplicazione delle righe in memoria.

• 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

IndexSeek

Rappresenta una scansione dinamica in cui le righe restituite possono essere parametrizzate dai dati di runtime e potrebbero non rientrare in un singolo intervallo sequenziale dell'indice. Inoltre, per soddisfare la query, potrebbero essere eseguite più scansioni distinte.

Ad esempio, una query in cui user è uguale a $user_id e date_placed è uguale a "2025-08-10" in esecuzione su un indice di ["user" ASC, "date_placed" ASC], utilizzerà il valore della variabile $user_id in fase di runtime e il vincolo "2025-08-10" su date_placed per limitare gli intervalli di scansione.

• IndexSeek
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| fields: [$user_1 ASC, $date_placed_1 ASC, $rid ASC]
| key: $key_1
| filter: $eq($user_1, $user_id) AND $eq($date_placed_1, "2025-08-10")
| records returned: 1
| records scanned: 1

Recupera

Esegue il back-join dell'identificatore della riga fornita ai contenuti effettivi della riga dallo spazio di archiviazione principale. Fetch è obbligatorio se un nodo principale (o il risultato finale della query) richiede un sottoinsieme di campi dei documenti.

• Fetch
|  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 ordine deterministico.

• TableScan
|  order: STABLE
|  properties: *
|  records returned: 1
|  records scanned: 1
|  source: (default)#/**/collection

Applica

Esegue un join tra due set di dati (input e map) eseguendo l'iterazione di ogni riga di input e, per ogni riga, analizzando e restituendo i risultati dal lato map.

join_type indica il tipo di join. Ad esempio, LEFT_OUTER significa che tutte le righe di input sono incluse almeno una volta nell'output. Se una riga input non trova risultati dal lato map, verrà comunque inclusa, con valori null per le colonne dal lato map.

• Apply
|  join_type: LEFT_OUTER
|
└── • input tree
|     ...
└── • map tree
      ...

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 limite di memoria della 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 aggregato specializzato che mantiene lo stato solo per un singolo gruppo alla volta, riducendo il picco di memoria utilizzata. Utilizzato quando il nodo secondario sottostante restituisce i gruppi in sequenza. Ad esempio, quando raggruppi per valori distinti di un campo utilizzando 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 del set 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 la memoria utilizzata. In questo modo, gli ordinamenti possono essere eseguiti su un insieme arbitrariamente grande di record, purché 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ù elementi secondari e l'ordine dei risultati restituiti non è deterministico.

• Concat
├── • Fetch
...
├── • Fetch

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 in modo selettivo le righe se e solo se corrispondono all'espressione fornita.

• Filter
|  expression: $eq(foo, "bar")
|  records returned: 1

RecordCount

Conta il numero di righe prodotte dal nodo secondario ed emette il conteggio corrente nella variabile specificata nell'attributo count.

• RecordCount
|  count: $row_number_1
|  records returned: 1

Valori

Produce una sequenza di valori letterali su cui lavorare. Utilizzato principalmente quando un insieme di documenti viene fornito come input per una query.

• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]

Unnest

Annulla la nidificazione del 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 prestabilito di righe prodotte dal nodo secondario.

• Offset
|  offset: 10
|  records returned: 1