↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本。 PostgreSQL 9.3 已结束支持。 2018-11-08. 请参阅 当前版本手册.

46.6. 执行器 #

执行器接收由规划器/优化器创建的计划,并递归地处理它,以提取所需的行集合。这本质上是一种按需拉取的流水线机制。每当某个计划节点被调用时,它必须再交付一行,或者报告自己已经完成了行的交付。

为了给出一个具体示例,假设顶层节点是一个 MergeJoin 节点。在执行归并之前,必须先取到两行(每个子计划各一行)。因此执行器会递归调用自身去处理这些子计划(从挂接在 lefttree 上的子计划开始)。新的顶层节点,也就是左子计划的顶层节点,假设是一个 Sort 节点,那么又需要通过递归来取得一个输入行。Sort 的子节点可能是一个 SeqScan 节点,它表示真正去读取一个表。执行该节点会使执行器从表中取出一行,并把它返回给调用者节点。Sort 节点会反复调用它的子节点,以取得所有待排序的行。当输入耗尽时(子节点返回的是 NULL 而不是一行),Sort 代码就执行排序,并最终能够返回它的第一条输出行,也就是排序后的第一行。它会把其余行保存起来,以便在后续请求中按排序后的顺序交付这些行。

MergeJoin 节点同样会向它的右子计划请求第一行。然后它比较这两行,看它们是否可以连接;如果可以,就向调用者返回一条连接结果行。在下一次调用时,或者在当前这一对输入无法连接时立即,它会前进到某一个表的下一行或另一个表的下一行(取决于比较结果),并再次检查是否匹配。最终,其中一个子计划会耗尽,MergeJoin 节点就返回 NULL,以表明无法再形成更多连接结果行。

复杂查询可能涉及许多层计划节点,但总体方法是相同的:每个节点在每次被调用时,都会计算并返回它的下一条输出行。每个节点还负责应用规划器分配给它的任何选择或投影表达式。

执行器机制用于求值全部四种基本 SQL 查询类型:SELECT、INSERT、UPDATE 和 DELETE。对于 SELECT,顶层执行器代码只需要把查询计划树返回的每一行发送给客户端。对于 INSERT,每个返回的行会被插入到为该 INSERT 指定的目标表中。这项工作是在一个名为 ModifyTable 的特殊顶层计划节点中完成的。(一个简单的 INSERT ... VALUES 命令会创建一棵极为简单的计划树,它只包含一个计算单条结果行的 Result 节点,以及位于其上执行插入的 ModifyTable。但 INSERT ... SELECT 可能需要执行器机制的全部能力。)对于 UPDATE,规划器会安排每个计算得到的行包含所有被更新列的值,再加上原始目标行的 TID(tuple ID,即元组 ID 或行 ID);这些数据会被送入 ModifyTable 节点,该节点利用这些信息创建一个新的更新后行,并将旧行标记为已删除。对于 DELETE,计划实际返回的唯一列就是 TID,而 ModifyTable 节点只需利用该 TID 访问每个目标行并将其标记为已删除。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.