9.3 9.4 9.5 9.6 10 11 12 13 14
阿里云PostgreSQL 问题报告 纠错本页面

51.6. 执行器

执行器接手规划器/优化器创建的计划,并递归地处理之以抽取所需的行集。这本质上是一种需求拉动的管道机制。每次一个计划节点被调用时,它必须交付一个或多个行,或者报告已经完成了行的交付。

为了提供一个具体例子,假设顶层节点是一个MergeJoin节点。在归并完成之前,两个行必须先被获取(每一个来自于一个子计划)。因此执行器递归地调用它自己去处理子计划(从附加在lefttree的子计划开始)。新的顶层节点(左子计划的顶层节点),我们说是一个Sort节点,并且又要递归来获取一个输入行。Sort的子节点可以是一个SeqScan节点,表示真正地读取一个表。该节点的执行将会使执行器从表中获取一行并将它返回给调用节点。Sort节点将反复调用它的子节点来获得所有需要排序的行。当输入耗尽后(子节点将返回一个NULL来标识),Sort节点执行排序,并且最后能够返回它的第一个输出行,及排序后的第一个。它会把剩下的行保存下来,这样它可以根据后续的要求按照排好的顺序返回这些行。

MergeJoin节点也会相似地从其右子计划要求第一个行。然后它会比较两个子节点提供的行看它们是否能被连接,如果可以它会返回一个连接行给调用者。在下一次调用时,或者它无法连接当前的输入对时,它会前进到一个表或另一个表的下一行(取决于比较的结果),并再次检查匹配。最后,某个子计划耗尽,MergeJoin节点返回NULL表示它没有更多连接行可以提供。

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

执行器机制被用于评估四种基本SQL查询类型:SELECT, INSERT,UPDATE, 和 DELETE。 对于SELECT,顶层执行器代码只需要发送查询计划树返回的每个行给客户端。 INSERT ... SELECT,UPDATE, 和 DELETE 是在一个被称为ModifyTable的特殊顶层计划节点下面的有效的SELECT

INSERT ... SELECT 把行输送到ModifyTable来执行插入。 对于UPDATE,规划器会安排每一个计算行包含所有被更新的列值,加上原始目标行的TID(元组ID或行ID); 这些数据也会被输送到一个ModifyTable节点,该节点将利用这些信息创建一个新的被更新行并标记旧行为被删除。 对于DELETE,被计划实际返回的唯一的列是TID,ModifyTable节点简单地使用TID访问每一个目标行并将其标记为被删除。

一个简单的INSERT ... VALUES命令会创建一个由一个Result节点组成的简单计划树, 只计算一个结果行,然后输送到ModifyTable来执行插入。