На этой странице объясняется вывод запроса, выполненного с помощью Query Explain. Чтобы узнать, как выполнить запрос с помощью Query Explain, см. раздел Анализ выполнения запроса с помощью Query Explain .
Общие концепции
В дереве выполнения используются следующие общие понятия и термины.
Строки и записи
Термины «строка» и «запись» используются для общего обозначения документа или записи индекса.
Переменные
Символ $
обозначает переменную, которая создаётся или упоминается в дереве выполнения. Например: $foo_1
. Эти переменные обычно используются для ссылки на содержимое документа или значение выражения, вычисляемого во время выполнения запроса.
В узлах выполнения могут появляться следующие внутренние переменные:
-
$__key__
— ключ — это внутренний идентификатор документа. Это абсолютный, уникальный идентификатор, включающий проект, базу данных и полный путь к документу. -
$__id__
— идентификатор документа в коллекции. Он уникален в пределах одной коллекции.
Рассмотрим пример, в котором узел Compute
используется для вычисления __id__
из документа __key__
:
Compute
| $__id__1: _id($__key__)
| records returned: 1
Ограничения и диапазоны
Некоторые узлы сканирования используют атрибуты constraints
и ranges
для описания диапазона сканируемых значений. Эти атрибуты используют формат дерева диапазонов, содержащего список значений. Эти значения соответствуют упорядоченному списку ключей, указанных в определении индекса. Например, первый диапазон, указанный в дереве, здесь (1..5]
, соответствует ограничениям на первый ключ, здесь a
, в упорядоченном списке ключей:
| index: type=CollectionGroupIndex, id=CICAgOjXh#EK, keys=[a ASC, b ASC, __key__ ASC]
| constraints: /
|----(1..5]
|----[1L]
Каждый уровень отступа указывает на ограничение, применяемое к следующему ключу в списке. Квадратные скобки обозначают включающий диапазон, круглые — исключающий. В данном случае ограничение преобразуется в 1 < "a" <= 5
и "b" = 1
.
В следующем примере с несколькими ветвями для a
ограничение соответствует 1 < a <= 5 OR a = 10
:
| constraints: /
|----(1L, 5L]
|----[10L]
Ключевые переменные
В некоторых узлах сканирования (например, SequentialScan
) есть как список ключей как часть атрибута index
, так и отдельный атрибут keys
в узле Scan
. Атрибут keys
в узле Scan
обозначает имя переменной каждого ключа в определении индекса (по порядку). Эти переменные можно использовать для ссылки на значения времени выполнения сканируемого поля, расположенные выше в дереве выполнения.
В следующем примере значение поля user
для текущего документа сопоставляется с переменной $user_1
, а значение date_placed
с $date_placed_1
.
index: type=CollectionGroupIndex, id=CICAgOjXh4EK, keys=[user ASC, date_placed ASC, __key__ ASC]
keys: [user ASC, date_placed ASC, __key__ ASC]
Узлы исполнения
Дерево выполнения запроса может содержать следующие узлы.
SeekingScan
Представляет собой динамическое сканирование, при котором возвращаемые строки могут не принадлежать одному последовательному диапазону индекса, и для выполнения запроса необходимо выполнить несколько отдельных сканирований.
Например, запрос, где a
существует, а b
равно 1, работающий с индексом ["a" ASC, "b" ASC]
, должен будет выполнить сканирование и вернуть отдельный, потенциально непоследовательный диапазон для каждого отдельного значения a
. Это эффективнее полного TableScan
, но менее эффективно, чем одиночное SequentialScan
для составного индекса ["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
Последовательное сканирование
Представляет собой сканирование статического последовательного диапазона строк в хранилище, которое может быть выполнено за одну операцию чтения.
key ordering length
определяет количество ключей, которые необходимо сохранить и вернуть в исходном порядке. Для схемы [k1, k2, k3]
длина упорядочивания ключей, равная 0, означает, что сканирование может выполняться в любом порядке, 1 означает, что упорядочивание будет осуществляться по k1, но строки с одинаковым значением k1 могут быть упорядочены в любом порядке, а 3 возвращает документы в точно отсортированном порядке.
• 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
Представляет собой сканирование статического последовательного диапазона строк в хранилище с дедупликацией строк в памяти.
• 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
TableAccess
Выполняет обратное соединение предоставленного идентификатора строки с фактическим содержимым строки из основного хранилища. TableAccess
требуется, если родительский узел (или конечный результат запроса) требует подмножество полей из документов.
• TableAccess
| order: PRESERVE_INPUT_ORDER
| peak memory usage: 4.00 KiB (4,096 B)
| properties: *
| records returned: 1
LookupById
Выполняет объединение, выполняя поиск документов во внешней коллекции по их идентификаторам. Идентификаторы для поиска берутся из поля во входных документах. Результаты поиска добавляются в виде нового поля во входные документы.
• LookupById
| local_field: $localField_1
| foreign_datasource: (default)#/**/foreign
| output: $output_1
TableScan
Полное неупорядоченное сканирование коллекции. Используется, когда запрос выполняется без связанного индекса.
Порядок может быть либо STABLE
, либо UNDEFINED
, причем STABLE
обозначает детерминированный порядок.
• TableScan
| order: STABLE
| properties: *
| records returned: 1
| records scanned: 1
| source: (default)#/**/collection
HashAggregate
Реализация агрегатных операций с хэш-поддержкой. Требует материализации всей группы в памяти перед возвратом результата и не должна превышать лимит памяти запроса .
• HashAggregate
| aggregations: [sum($b_1) AS total]
| groups: [$a_1]
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 0
StreamAggregate
Специализированный агрегатный узел, который одновременно хранит состояние только одной группы, что снижает пиковое потребление памяти. Используется, когда базовый дочерний узел последовательно возвращает группы. Например, при группировке по отдельным значениям поля с использованием индекса по этому полю.
• StreamAggregate
| keys: [foo ASC, bar ASC]
| properties: Selection { baz }
| aggregations: [$sum($foo_1) AS baz]
MajorSort
Выполняет операцию сортировки по фиксированному набору свойств. Материализует все записи в памяти одновременно и возвращает отсортированные значения в порядке возрастания. Размер набора сортировки ограничен лимитом памяти запроса .
При указании дополнительного ограничения для уменьшения расхода памяти используется алгоритм сортировки по k-топ-элементам. С его помощью можно выполнять сортировку на сколь угодно большом наборе записей, пока объём памяти, занимаемый для хранения k рассматриваемых элементов, не превышает заданного ограничения.
• MajorSort
| fields: [a ASC, b DESC]
| limit: 10
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 1
Конкат
Объединяет результаты нескольких дочерних узлов и возвращает результат родительскому узлу. Этот узел не дедуплицирует результаты, появляющиеся в нескольких дочерних узлах, а порядок возвращаемых результатов не определён.
• Concat
├── • TableAccess
...
├── • TableAccess
Вычислить
Оценивает набор выражений, присваивая результаты набору переменных.
• Compute
| $user_1: user
| $full_name_1: str_concat($first_name_1, " ", $last_name_1)
| $address_1: UNSET
| records returned: 1
Фильтр
Выборочно возвращает строки только в том случае, если они соответствуют указанному выражению.
• Filter
| expression: $eq(foo, "bar")
| records returned: 1
Ценности
Создаёт последовательность литеральных значений для обработки. Используется в основном, когда в качестве входных данных для запроса предоставляется заданный список документов.
• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]
Unnest
Удаляет вложенное значение, созданное дочерним узлом.
• Unnest
| expression: foo AS unnested_foo
Предел
Ограничивает количество строк, возвращаемых родительскому узлу.
• Limit
| limit: 10
| records returned: 1
Компенсировать
Пропускает заданное количество строк, созданных дочерним узлом.
• Offset
| offset: 10
| records returned: 1