Riferimento all'esecuzione della query

Questa pagina illustra 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.

Concetti comuni

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 una voce di documento o 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.

Le seguenti variabili interne possono essere visualizzate nei nodi di esecuzione:

  • $__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 sua raccolta. È univoco all'interno di una singola raccolta.
  • $rid : l'ID riga è un identificatore interno per un documento nello spazio di archiviazione. È univoco all'interno di una singola raccolta.

Considera un esempio in cui viene utilizzato un nodo Compute per calcolare __id__ da __key__ del documento:

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 di 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 che appare nell'albero, in questo caso (1..5], corrisponde ai vincoli sulla prima chiave, in questo caso 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 (ad esempio 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 essere 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.

La key ordering length si riferisce al numero di chiavi che devono essere conservate e restituite nell'ordine delle chiavi originali. Per uno schema di [k1, k2, k3], una lunghezza di ordinamento delle chiavi pari a 0 significa che la scansione può restituire in qualsiasi ordine, 1 significa ordinare per k1, ma le righe con lo stesso valore k1 possono avere 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: [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 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

IndexSeek

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

Ad esempio, una query in cui user è uguale a $user_id e date_placed è uguale "2025-08-10" eseguita su un indice di ["user" ASC, "date_placed" ASC] utilizzerebbe 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 un back-join dell'identificatore della riga fornita ai contenuti effettivi della riga dallo spazio di archiviazione principale. Fetch è obbligatorio se un nodo padre (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. Viene utilizzato quando una query viene eseguita senza un indice associato.

L'ordine può essere STABLE o UNDEFINED, con STABLE che indica un ordinamento 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) scorrendo ogni riga di input e, per ogni riga, scansionando 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 aggregate. Richiede la materializzazione dell' intero gruppo in memoria prima di restituire il risultato e non deve superare il 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 di aggregazione specializzato che mantiene lo stato solo per un singolo gruppo alla volta, riducendo la memoria utilizzata massima. Viene utilizzato quando il nodo figlio sottostante restituisce i gruppi in sequenza. Ad esempio, quando si raggruppano i 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. Con questo algoritmo, gli ordinamenti possono essere eseguiti su un insieme di record arbitrariamente grande, a condizione che la memoria utilizzata per memorizzare gli elementi k 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 figli e restituisce il risultato al nodo padre. Questo nodo non deduplica i risultati che appaiono in più figli e l'ordine dei risultati restituiti non è deterministico.

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

Compute

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

RecordCount

Conta il numero di righe prodotte dal nodo figlio 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. Viene utilizzato principalmente quando viene fornito un elenco di documenti come input per una query.

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

Unnest

Esegue l'unnest del valore prodotto dal nodo figlio.

• Unnest
|  expression: foo AS unnested_foo

Limite

Limita il numero di righe restituite al nodo padre.

• Limit
|  limit: 10
|  records returned: 1

Offset

Salta un numero impostato di righe prodotte dal nodo figlio.

• Offset
|  offset: 10
|  records returned: 1