Referência de execução de consulta

Nesta página, explicamos a saída de uma consulta executada com o Query Explain. Para saber como executar uma consulta com o Query Explain, consulte Analisar a execução de consultas com o Query Explain.

Conceitos comuns

Os seguintes conceitos e termos comuns são usados em toda a árvore de execução.

Linhas e registros

Os termos linha e registro são usados para se referir genericamente a um documento ou entrada de índice.

Variáveis

As seguintes variáveis internas podem aparecer nos nós de execução:

  • __key__: a chave é um identificador interno de um documento. Esse é um identificador absoluto e exclusivo com o projeto, o banco de dados e o caminho completo do documento.
  • __id__: o ID é um identificador exclusivo de um documento na coleção. Ele é exclusivo em uma única coleção.
  • __$0__…__$N__: são variáveis específicas do contexto criadas ou referenciadas na árvore de execução. Essas variáveis geralmente são usadas para se referir ao conteúdo de um documento ou ao valor de uma expressão avaliada durante a execução de uma consulta.

Considere um exemplo em que um nó de extensão é usado para extrair o __id__ do documento __key__:

Extend
    |  expressions: [_id(__key__) AS __id__]
    |  records returned: 1

Restrições e intervalos

Alguns nós de verificação usam atributos constraints e ranges para descrever o intervalo de valores verificados. Esses atributos usam um formato de árvore de intervalo que contém uma lista de valores. Esses valores correspondem à lista ordenada de chaves que aparecem na definição do índice. Por exemplo, o primeiro intervalo que aparece na árvore, aqui (1..5], corresponde às restrições na primeira chave, aqui a, na lista ordenada de chaves:

| index: type=CollectionGroupIndex, id=CICAgOjXh#EK, keys=[a ASC, b ASC, __key__ ASC]
| constraints: /
               |----(1..5]
                    |----[1L]

Cada nível de indentação indica a restrição aplicada à próxima chave na lista. Os colchetes representam um intervalo inclusivo, e os parênteses, um intervalo exclusivo. Nesse caso, a restrição é traduzida como 1 < "a" <= 5 e "b" = 1.

No exemplo a seguir com várias ramificações para a, a restrição corresponde a 1 < a <= 5 OR a = 10:

| constraints: /
               |----(1L, 5L]
               |----[10L]

Variáveis principais

Em alguns nós de verificação (como SequentialScan), há uma lista de chaves como parte do atributo index e um atributo keys separado no nó Scan. O atributo keys no nó Scan indica o nome da variável de cada chave na definição do índice, em ordem. As variáveis podem ser usadas para fazer referência aos valores de tempo de execução do campo verificado mais acima na árvore de execução.

No exemplo a seguir, o valor do campo user para o documento atual é mapeado para a variável __$6__ e o valor de date_placed para __$7__.

index: type=CollectionGroupIndex, id=CICAgOjXh4EK, keys=[user ASC, date_placed ASC, __path__ ASC]
keys: [__$6__ ASC, __$7__ ASC, __path__ ASC]

Nós de execução

Uma árvore de execução de consulta pode conter os seguintes nós.

SeekingScan

Representa uma verificação dinâmica em que as linhas retornadas podem não estar em um único intervalo sequencial do índice, e várias verificações distintas precisam ser realizadas para satisfazer a consulta.

Por exemplo, uma consulta em que a existe e b é igual a 1, trabalhando em um índice de ["a" ASC, "b" ASC], precisaria verificar e retornar um intervalo separado, potencialmente não sequencial, para cada valor distinto de a. Isso é mais eficiente do que um TableScan completo, mas menos eficiente do que um único SequentialScan em um índice composto de ["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

Representa uma verificação de um intervalo estático e sequencial de linhas no armazenamento que pode ser realizada em uma única operação de leitura.

O key ordering length se refere ao número de chaves que precisam ser preservadas e retornadas na ordem original. Para um esquema de [k1, k2, k3], um comprimento de ordenação de chave 0 significa que a verificação pode retornar em qualquer ordem, 1 significa ordem por k1, mas linhas com o mesmo valor k1 podem vir em qualquer ordem, 3 retorna documentos em ordem classificada exata.

• 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

Representa uma verificação de um intervalo estático e sequencial de linhas no armazenamento com deduplicação na memória das linhas.

• 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

Faz uma junção de volta do identificador da linha fornecida com o conteúdo real da linha do armazenamento principal. TableAccess é obrigatório se um nó pai (ou o resultado da consulta final) exigir um subconjunto de campos dos documentos.

• TableAccess
|  order: PRESERVE_INPUT_ORDER
|  peak memory usage: 4.00 KiB (4,096 B)
|  properties: *
|  records returned: 1

TableScan

Uma verificação completa e não ordenada de uma coleção. Usado quando uma consulta é executada sem um índice associado.

A ordem pode ser STABLE ou UNDEFINED, sendo que STABLE indica uma ordenação determinística.

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

HashAggregate

Implementação com hash de operações de agregação. Exige a materialização do grupo completo na memória antes de retornar o resultado e não pode exceder o limite de memória da consulta.

• HashAggregate
|  aggregations: [sum(__$0__) AS total]
|  groups: [a]
|  peak memory usage: 4.00 KiB (4,096 B)
|  records returned: 0

StreamAggregate

Nó agregado especializado que mantém o estado de um único grupo por vez, reduzindo o uso máximo de memória. Usado quando o nó filho subjacente retorna grupos sequencialmente. Por exemplo, ao agrupar por valores distintos de um campo usando um índice nesse campo.

• StreamAggregate
|  keys: [foo ASC, bar ASC]
|  properties: Selection { baz }
|  aggregations: [$sum(foo) AS baz]

MajorSort

Realiza uma operação de classificação em um conjunto fixo de propriedades. Materializa todos os registros na memória de uma só vez e retorna os valores classificados em ordem. O tamanho do conjunto de classificação é limitado pelo limite de memória da consulta.

Quando um limite subsequente é fornecido, um algoritmo de classificação top-k é usado para reduzir o uso de memória. Com ele, as classificações podem ser realizadas em um conjunto arbitrariamente grande de registros, desde que a memória usada para armazenar os elementos considerados k não exceda o limite.

• MajorSort
|  fields: [a ASC, b DESC]
|  limit: 10
|  peak memory usage: 4.00 KiB (4,096 B)
|  records returned: 1

Concat

Concatena os resultados de vários nós filhos e retorna o resultado para o nó pai. Esse nó não remove resultados duplicados que aparecem em vários filhos, e a ordem dos resultados retornados não é determinista.

• Concat
├── • TableAccess
...
├── • TableAccess

Restringir

Projeta um conjunto de propriedades a serem transmitidas para o nó pai. Reduz o uso de memória ao impedir a propagação de campos não utilizados assim que eles se tornam irrelevantes para o restante da consulta.

• Restrict
|  expressions: [foo AS foo, bar AS bar]
|  records returned: 0

Estender

Adiciona um conjunto de campos a cada linha no conjunto de resultados. Usado ao adicionar campos a um documento e como um nó intermediário para oferecer suporte a operações mais complexas.

• Extend
|  expressions: ["bar" AS foo]
|  records returned: 1

Filtro

Retorna linhas se e somente se elas corresponderem à expressão fornecida.

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

Valores

Produz uma sequência de valores literais para trabalhar. Usado principalmente quando um conjunto de documentos é fornecido como entrada para uma consulta.

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

ReplaceWith

Substitui os campos das linhas produzidas pelo nó filho com os campos da expressão map fornecida.

• ReplaceWith
|  map: map("full_name", str_concat(first_name, " ", last_name)), current_context())
|  records returned: 1

Unnest

Desaninha o valor produzido pelo nó filho.

• Unnest
|  expression: foo AS unnested_foo

Limite

Limita o número de linhas retornadas ao nó principal.

• Limit
|  limit: 10
|  records returned: 1

Deslocamento

Ignora um número definido de linhas produzidas pelo nó filho.

• Offset
|  offset: 10
|  records returned: 1

Soltar

Descarta um conjunto especificado de campos dos resultados produzidos pelo nó filho.

• Drop
|  fields to drop: [__key__]
|  records returned: 1