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

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

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

Append

Append

依次访问子计划并合并其输出行。

当前查看 PostgreSQL 18。

中文定义与说明

依次访问子计划并合并其输出行。

核心节点标识:T_Append;EXPLAIN 名称:Append。

本版本源码中的并行执行或观测回调:ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM。回调的存在不表示该节点必然支持共享并行扫描;在并行工作进程中执行也不等于具有并行感知能力。

同版本中文手册节选

EXPLAIN ANALYZE 测得的运行时间,可能以两种重要方式偏离同一查询的正常执行时间。第一,由于不会向客户端传递任何输出行,因此网络传输开销不会被计入。除非指定了 SERIALIZE,I/O 转换开销同样也不会被计入。第二,EXPLAIN ANALYZE 附加的测量开销本身可能相当可观,尤其是在操作系统调用 gettimeofday() 较慢的机器上。可以使用 pg_test_timing 工具来测量系统上的计时开销。

不应将 EXPLAIN 结果外推到与实际测试场景差异很大的情况。例如,在一个很小的表上得到的结果,不能假定也适用于大型表。规划器的代价估计不是线性的,因此它可能会为更大或更小的表选择不同的计划。一个极端示例是:对于只占用一个磁盘页的表,无论索引是否可用,几乎总会得到顺序扫描计划。规划器认识到,无论如何处理该表都需要一次磁盘页读取,因此再额外读取页面去查看索引并没有价值。(前面的 polygon_tbl 示例已经展示过这种情况。)

在某些情况下,实际值和估计值不会很好地对应,但这并不表示出现了问题。其中一种情况是,计划节点的执行会被 LIMIT 或类似效果提前截断。例如,在前面用过的 LIMIT 查询中:

Index Scan 节点的估计代价和行计数显示得像是它会运行到结束一样。但实际上,Limit 节点在拿到两行之后就停止请求更多行,因此实际行计数只有 2,运行时间也低于代价估计所暗示的水平。这并不是估计错误,只是估计值与真实值的显示方式不同而已。

查看完整中文手册与上下文。

本页开头的中文说明为 PG.CENTER 对编辑说明的翻译;手册节选保留对应版本中文文档原文。源码信息及手册示例不代表重新进行过运行测试。

说明

依次访问子计划并合并其输出行。

核心节点标签
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 17 → 18: 无变化。

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

相关条目

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