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