查询执行参考文档

本页介绍了使用“查询说明”功能执行的查询的输出。如需了解如何使用查询解释执行查询,请参阅使用查询解释分析查询执行

常见概念

执行树中使用了以下常见概念和术语。

行和记录

记录一词通常用于指代文档或索引条目。

变量

执行节点中可能会出现以下内部变量:

  • __key__ - 键是文档的内部标识符。这是包含项目、数据库和文档完整路径的绝对唯一标识符。
  • __id__ - 该 ID 是文档在其合集中的唯一标识符。 此 ID 在单个合集中是唯一的。
  • __$0__…__$N__ - 这些是上下文专用变量,在执行树中创建或引用。这些变量通常用于引用文档的内容或在执行查询期间求值的表达式的值。

下面是一个示例,其中使用 extend 节点从文档 __key__ 中提取 __id__

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

约束条件和范围

某些扫描节点使用 constraintsranges 属性来描述要扫描的值范围。这些属性使用范围树格式,其中包含值列表。这些值与索引定义中显示的有序键列表相对应。例如,树中显示的第一个范围(此处为 (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 属性中包含键列表,Scan 节点中还有单独的 keys 属性。Scan 节点中的 keys 属性表示索引定义中每个键的变量名称(按顺序)。这些变量可用于引用执行树中更高层级的已扫描字段的运行时值。

在以下示例中,当前文档的 user 字段的值会映射到变量 __$6__,而 date_placed 的值会映射到 __$7__

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

执行节点

查询执行树可以包含以下节点。

SeekingScan

表示动态扫描,其中返回的行可能不在索引的单个顺序范围内,并且必须执行多个不同的扫描才能满足查询。

例如,如果查询中存在 ab 等于 1,并且在 ["a" ASC, "b" ASC] 索引上运行,则需要为 a 的每个不同的值扫描并返回单独的可能非连续范围。这比完整的 TableScan 更高效,但比对 ["b" ASC, "a" ASC] 复合索引的单个 SequentialScan 更低效。

• 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

表示对存储空间中静态、顺序行范围的扫描,可在单次读取操作中执行。

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: [__$1__ ASC, __$2__ 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: [__$1__ ASC, __$2__ 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

TableScan

对集合的完整无序扫描。在运行不含关联索引的查询时使用。

顺序可以是 STABLEUNDEFINED,其中 STABLE 表示确定性排序。

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

HashAggregate

基于哈希的汇总操作实现。需要先在内存中具体化整个组,然后才能返回结果,并且不得超过查询内存限制

• HashAggregate
|  aggregations: [sum(__$0__) AS total]
|  groups: [a]
|  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) 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

串联多个子节点的结果,并将结果返回给父节点。此节点不会删除出现在多个子节点中的重复结果,并且返回结果的顺序是不确定的。

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

限制

投影一组要传递给其父级节点的属性。通过在未使用的字段与查询的其余部分无关时立即阻止其传播,从而减少内存用量。

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

延期

向结果集中的每一行添加一组字段。用于向文档添加字段,并用作中间节点以支持更复杂的操作。

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

过滤

仅在行与所提供的表达式匹配时才选择性返回相应行。

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

生成要处理的一组字面量值。主要用于将文档列表作为查询的输入提供时。

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

ReplaceWith

将子节点生成的行中的字段替换为所提供的 map 表达式中的字段。

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

展开

展开子节点生成的值。

• Unnest
|  expression: foo AS unnested_foo

限制

限制返回给父节点的行数。

• Limit
|  limit: 10
|  records returned: 1

偏移值

跳过子节点生成的一组行。

• Offset
|  offset: 10
|  records returned: 1

放置

从子节点生成的结果中删除一组指定的字段。

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