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

52.6. 执行器

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

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

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

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

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

INSERT ... SELECT feeds the rows up to ModifyTable for insertion. For UPDATE, the planner arranges that each computed row includes all the updated column values, plus the TID (tuple ID, or row ID) of the original target row; this data is fed up to the ModifyTable node, which uses the information to create a new updated row and mark the old row deleted. For DELETE, the only column that is actually returned by the plan is the TID, and the ModifyTable node simply uses the TID to visit each target row and mark it deleted. For MERGE, the planner joins the source and target relations, and includes all column values required by any of the WHEN clauses, plus the TID of the target row; this data is fed up to the ModifyTable node, which uses the information to work out which WHEN clause to execute, and then inserts, updates or deletes the target row, as required.

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