2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 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

51.6. 執行器 #

執行器 接收由規劃器/最佳化器建立的計劃,並遞迴地處理它以提取所需的行集。這本質上是一個需求拉動的管道機制。每次呼叫一個計劃節點時,它必須再提供一行,或者報告它已完成提供行。

為了提供一個具體的例子,假設頂層節點是一個 MergeJoin 節點。在執行任何合併之前,必須獲取兩行(每行來自一個子計劃)。因此,執行器遞迴地呼叫自身來處理子計劃(它從附加到 lefttree 的子計劃開始)。新的頂層節點(左子計劃的頂層節點),比如說,是一個 Sort 節點,並且再次需要遞迴來獲取輸入行。 Sort 的子節點可能是一個 SeqScan 節點,代表實際讀取一個表。執行此節點會導致執行器從表中獲取一行,並將其返回給呼叫節點。 Sort 節點將反覆呼叫其子節點來獲取要排序的所有行。當輸入耗盡時(由子節點返回 NULL 而不是行來指示), Sort 程式碼執行排序,並最終能夠返回其第一行輸出,即按排序順序排列的第一行。它會將剩餘的行儲存起來,以便能夠響應後續的需求以排序順序提供它們。

MergeJoin 節點類似地請求其右子計劃的第一行。然後它比較這兩行以確定它們是否可以連線;如果可以,它將連線行返回給其呼叫者。在下一次呼叫時,或者如果它無法連線當前輸入對,它會推進一個表或另一個表的下一行(取決於比較結果),並再次檢查匹配。最終,其中一個子計劃或另一個子計劃耗盡, MergeJoin 節點返回 NULL,表示無法形成更多連線行。

複雜的查詢可能涉及多個級別的計劃節點,但總體方法是相同的:每個節點在每次被呼叫時都會計算並返回其下一行輸出。每個節點還負責應用規劃器分配給它的任何選擇或投影表示式。

執行器機制用於評估所有五種基本 SQL 查詢型別: SELECTINSERTUPDATEDELETEMERGE。對於 SELECT,頂層執行器程式碼只需要將查詢計劃樹返回的每一行傳送給客戶端。 INSERT ... SELECTUPDATEDELETEMERGE 實際上是 SELECT 的變體,它們有一個特殊的頂層計劃節點 ModifyTable

INSERT ... SELECT 將行饋送到 ModifyTable 進行插入。對於 UPDATE,規劃器安排計算出的每一行都包含所有更新的列值,以及原始目標行的 TID(元組 ID,或行 ID);此資料被饋送到 ModifyTable 節點,該節點使用該資訊建立一條新的更新行並將舊行標記為已刪除。對於 DELETE,計劃中實際返回的唯一列是 TID, ModifyTable 節點僅使用 TID 來訪問每一目標行並將其標記為已刪除。對於 MERGE,規劃器連線源和目標關係,幷包含任何 WHEN 子句所需的全部列值,以及目標行的 TID;此資料被饋送到 ModifyTable 節點,該節點使用這些資訊來確定執行哪個 WHEN 子句,然後根據需要插入、更新或刪除目標行。

一個簡單的 INSERT ... VALUES 命令會建立一個簡單的計劃樹,由一個 Result 節點組成,該節點僅計算一行結果,然後將其饋送到 ModifyTable 以執行插入。

提交更正

如果您在本應正確的內容中發現任何不正確之處、與您對特定功能的實際體驗不符之處,或需要進一步澄清之處,請使用 此表單 報告文件問題。