2024 年 9 月 26 日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:开发版本
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1

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

提交更正

如果您在文档中看到任何不正确的内容、与您对特定功能的体验不符的内容或需要进一步说明的内容,请使用 此表格 报告文档问题。