执行器 接收规划器/优化器创建的计划,并递归地处理它,以提取所需的行集。这本质上是一个按需拉取的管道机制。每次调用一个计划节点时,它必须交付一行,或报告它已完成交付行。
为了提供一个具体的示例,假设顶部节点是一个 MergeJoin
节点。在进行任何合并之前,必须获取两行(分别来自每个子计划)。因此,执行器递归地调用自身来处理子计划(它从附加到 lefttree
的子计划开始)。新的顶部节点(左子计划的顶部节点)假设是一个 Sort
节点,并且再次需要递归来获取输入行。Sort
节点的子节点可能是一个 SeqScan
节点,表示实际读取表。执行此节点会导致执行器从表中获取一行并将其返回给调用节点。Sort
节点将重复调用其子节点以获取要排序的所有行。当输入耗尽时(如子节点返回 NULL 而不是一行所指示的那样),Sort
代码执行排序,并最终能够返回其第一行输出,即按排序顺序的第一行。它保留存储的其余行,以便在响应后续请求时按排序顺序交付它们。
MergeJoin
节点类似地从其右子计划请求第一行。然后,它比较这两行以查看它们是否可以连接;如果可以,则它将其连接行返回给其调用者。在下一次调用时,或者如果它无法连接当前输入对,则它前进到其中一个表的下一行(取决于比较结果),并再次检查匹配项。最终,一个子计划或另一个子计划耗尽,并且 MergeJoin
节点返回 NULL,指示无法形成更多连接行。
复杂的查询可能涉及多个级别的计划节点,但一般方法是相同的:每次调用时,每个节点都会计算并返回其下一行输出。每个节点还负责应用规划器分配给它的任何选择或投影表达式。
执行器机制用于评估所有五种基本 SQL 查询类型:SELECT
、INSERT
、UPDATE
、DELETE
和 MERGE
。对于 SELECT
,顶层执行器代码只需要将查询计划树返回的每一行发送到客户端。INSERT ... SELECT
、UPDATE
、DELETE
和 MERGE
实际上是 ModifyTable
这个特殊顶层计划节点下的 SELECT
。
INSERT ... SELECT
将行反馈到 ModifyTable
以进行插入。对于 UPDATE
,规划器安排每个计算行都包含所有更新的列值,以及原始目标行的 TID(元组 ID 或行 ID);此数据被反馈到 ModifyTable
节点,该节点使用该信息创建新的更新行并标记旧行已删除。对于 DELETE
,计划实际返回的唯一列是 TID,并且 ModifyTable
节点仅使用 TID 来访问每个目标行并将其标记为已删除。对于 MERGE
,规划器连接源关系和目标关系,并包含任何 WHEN
子句所需的所有列值,以及目标行的 TID;此数据被反馈到 ModifyTable
节点,该节点使用该信息来确定要执行哪个 WHEN
子句,然后根据需要插入、更新或删除目标行。
一个简单的 INSERT ... VALUES
命令会创建一个由单个 Result
节点组成的简单计划树,该节点仅计算一行结果,并将其反馈给 ModifyTable
以执行插入。
如果您在文档中发现任何不正确、与您特定功能体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。