↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

百科 / 执行计划节点 / 组合

Append

Append

遍历各子计划并合并其输出行。

当前查看 PostgreSQL 18.6。

说明

遍历各子计划并合并其输出行。

核心节点标签
T_Append
结构化 EXPLAIN 节点类型
Append
输入
多个子计划
输出
合并后的元组
执行器初始化函数
ExecInitAppend
内存机制
unclassified

EXPLAIN 名称与属性

结构化格式使用上述 Node Type。文本格式名称还可能包含操作、策略、连接类型、扫描方向或聚合阶段属性。

此源码记录的文本名称:Append.

并行感知与并行安全是不同的计划属性。在并行工作进程内运行的节点不一定是并行感知节点。

内存与临时存储

本次抽取不为此节点设定统一的内存上限或落盘策略。请查看同一构建的实现、相关表达式或提供方。

并行执行与运行信息采集

以下源码回调可以协调执行或收集工作进程的测量数据。回调存在不代表该节点普遍支持共享并行扫描或共享状态。

此构建的回调:ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.

同版本手册说明

通常 EXPLAIN 显示规划器创建的每个节点。但执行器有时可以根据规划阶段尚不可知的参数值,判定某些节点无法产生任何行,因此不必执行。(目前仅会发生在扫描分区表的 Append 或 MergeAppend 节点的子节点上。)此时 EXPLAIN 省略这些节点,改为显示 Subplans Removed: N。

每当 PostgreSQL 需要将来自多个源的行合并成一个结果集时,它就会使用 Append 或 MergeAppend 计划节点。这种情况常见于实现 UNION ALL 或扫描分区表时。这样的节点和其他任何计划中的情形一样,也可以用于并行计划。不过,在并行计划中,规划器也可能改用 Parallel Append 节点。

当 Append 节点用于并行计划时,每个进程都会按照子计划出现的顺序执行它们,因此所有参与进程会协作执行第一个子计划直到其完成,然后再大致同时转向第二个子计划。而当使用 Parallel Append 时,执行器会尽可能均匀地将参与进程分散到各个子计划上,从而使多个子计划能够同时执行。这样既避免了争用,也避免让那些从未执行某个子计划的进程承担其启动代价。

此外,与在并行计划中只能包含部分子计划的普通 Append 节点不同,Parallel Append 节点既可包含部分子计划,也可包含非部分子计划。非部分子计划只由一个进程扫描,因为多次扫描会产生重复结果。因此,即使没有高效的部分计划,拼接多个结果集的计划也能实现粗粒度并行。例如,针对分区表的查询,可能只有借助不支持并行扫描的索引才能高效执行。规划器可能选择使用 Parallel Append 拼接多个普通 Index Scan 计划;每次索引扫描都必须由单个进程完整执行,但不同扫描可以由不同进程同时执行。

本版手册中的示例

示例摘自 PostgreSQL 18.6 手册;本百科未实际执行此示例。

当 UPDATE 、 DELETE 或 MERGE 命令影响分区表或继承层次时,输出可能像这样:

EXPLAIN UPDATE gtest_parent SET f1 = CURRENT_DATE WHERE f2 = 101;

                                       QUERY PLAN
----------------------------------------------------------------------------------------
 Update on gtest_parent  (cost=0.00..3.06 rows=0 width=0)
   Update on gtest_child gtest_parent_1
   Update on gtest_child2 gtest_parent_2
   Update on gtest_child3 gtest_parent_3
   ->  Append  (cost=0.00..3.06 rows=3 width=14)
         ->  Seq Scan on gtest_child gtest_parent_1  (cost=0.00..1.01 rows=1 width=14)
               Filter: (f2 = 101)
         ->  Seq Scan on gtest_child2 gtest_parent_2  (cost=0.00..1.01 rows=1 width=14)
               Filter: (f2 = 101)
         ->  Seq Scan on gtest_child3 gtest_parent_3  (cost=0.00..1.01 rows=1 width=14)
               Filter: (f2 = 101)

执行器实现说明

说明:每个 Append 节点包含一个或多个必须逐一处理的子计划,方向可以正向或反向。执行第 whichplan 个子计划取回元组,直到它不再返回元组,然后关闭该计划并启动下一个。

Append 节点不使用左、右子树,而是维护一个子计划列表,因此典型的 Append 节点在计划树中如下所示:

... / Append -------+------+------+--- nil / \ | | | nil nil ... ... ... subplans

Append 节点目前用于并集操作,也用于需要扫描多个关系的继承查询。例如,在标准的 person/student/employee/student-emp 示例中,student 和 employee 继承自 person,而 student-emp 同时继承自 student 和 employee,查询如下:

| Append -------+-------+--------+--------+ / \ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp

核心源码中的 EXPLAIN 标识

case T_Append:
			pname = sname = "Append";
			break;

本构建中的 EXPLAIN 标签

文本格式标签结构化节点标识
AppendAppend

相关条目

文档与源码

来源构建
版本
18.6
构建
PostgreSQL 18.6 source archive
来源指纹
555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f

版本比较

PostgreSQL 10 → 11: 属性变化。

以下差异保留原始字段名与英文源描述。

--- PostgreSQL 10
+++ PostgreSQL 11
@@ -2,7 +2,12 @@
   "initializer": "ExecInitAppend",
   "memory_mechanism": "unclassified",
   "node_tag": "T_Append",
-  "parallel_callbacks": [],
+  "parallel_callbacks": [
+    "ExecAppendEstimate",
+    "ExecAppendInitializeDSM",
+    "ExecAppendInitializeWorker",
+    "ExecAppendReInitializeDSM"
+  ],
   "partial_modes": [],
   "strategies": [],
   "text_names": [

比较已记录的接口与属性,排除来源指纹和构建元数据。某个样本中没有记录,不能据此判断实际引入或移除的版本。

相关条目

导出 JSON · 返回执行计划节点 · 收录范围为 PostgreSQL 10 至 20;最早采样版本不一定是实际引入版本。