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 以执行插入。