Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16

52.6. 执行器

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

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

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

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

执行器机制用于评估所有五种基本的SQL查询类型:SELECTINSERTUPDATEDELETEMERGE。 对于SELECT,顶层执行器代码只需要将查询计划树返回的每一行发送给客户端。 INSERT ... SELECTUPDATEDELETEMERGE实际上是在一个名为ModifyTable的特殊顶层计划节点下的 SELECT

INSERT ... SELECT 将行提供给 ModifyTable 进行插入。 对于 UPDATE,规划器安排每个计算出的行包含所有更新列的值, 加上原始目标行的 TID (元组ID或行ID);这些数据被提供给 ModifyTable 节点,该节点使用这些信息创建一个新的更新行并标记旧行已删除。 对于 DELETE,计划实际返回的唯一列是TID, ModifyTable 节点只需使用TID访问每个目标行并将其标记为已删除。 对于 MERGE, 规划器连接源和目标关系,并包含所有 WHEN 子句所需的列值,加上目标行的TID; 这些数据被提供给 ModifyTable 节点,该节点使用这些信息来决定执行哪个 WHEN 子句,然后根据需要插入、更新或删除目标行。

一个简单的INSERT ... VALUES命令创建了一个简单的计划树,由一个单独的Result节点组成, 该节点仅计算一个结果行,将其传递给ModifyTable执行插入操作。