支援的版本:目前 (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

19.7. 查詢規劃 #

19.7.1. 規劃器方法組態 #

這些組態參數提供了一種粗略的方法來影響查詢最佳化器選擇的查詢計畫。如果最佳化器為特定查詢選擇的預設計畫不是最佳的,一個暫時性的解決方案是使用這些組態參數之一來強制最佳化器選擇不同的計畫。改進最佳化器選擇的計畫品質的更好方法包括調整規劃器成本常數(請參閱第 19.7.2 節),手動執行ANALYZE,增加default_statistics_target組態參數的值,並使用ALTER TABLE SET STATISTICS增加為特定欄位收集的統計資料量。

enable_async_append (boolean) #

啟用或停用查詢規劃器使用異步感知附加計畫類型。預設值為on

enable_bitmapscan (boolean) #

啟用或停用查詢規劃器使用位圖掃描計畫類型。預設值為on

enable_gathermerge (boolean) #

啟用或停用查詢規劃器使用收集合併計畫類型。預設值為on

enable_group_by_reordering (boolean) #

控制查詢規劃器是否產生一個計畫,該計畫將提供以計畫的子節點的鍵順序(例如索引掃描)排序的GROUP BY鍵。 停用時,查詢規劃器將產生一個僅排序以符合ORDER BY子句(如果有的話)的GROUP BY鍵的計畫。 啟用後,規劃器將嘗試產生更有效的計畫。預設值為on

enable_hashagg (boolean) #

啟用或停用查詢規劃器使用雜湊聚合計畫類型。預設值為on

enable_hashjoin (boolean) #

啟用或停用查詢規劃器使用雜湊聯結計畫類型。預設值為on

enable_incremental_sort (boolean) #

啟用或停用查詢規劃器使用增量排序步驟。預設值為on

enable_indexscan (boolean) #

啟用或停用查詢規劃器使用索引掃描和僅索引掃描計畫類型。預設值為on。另請參閱enable_indexonlyscan

enable_indexonlyscan (boolean) #

啟用或停用查詢規劃器使用僅索引掃描計畫類型(請參閱第 11.9 節)。預設值為on。 還必須啟用enable_indexscan設定,查詢規劃器才會考慮僅索引掃描。

enable_material (boolean) #

啟用或停用查詢規劃器使用實體化。不可能完全抑制實體化,但是關閉此變數會阻止規劃器插入實體化節點,除非在正確性要求的情況下。預設值為on

enable_memoize (boolean) #

啟用或停用查詢規劃器使用記憶化 (memoize) 方案,以便快取巢狀迴圈聯結中參數化掃描的結果。當目前參數的結果已存在於快取中時,此方案類型允許跳過對底層方案的掃描。不太常查詢的結果可能會從快取中逐出,以便為新條目騰出更多空間。預設值為 on

enable_mergejoin (boolean) #

啟用或停用查詢規劃器使用合併聯結方案類型。預設值為 on

enable_nestloop (boolean) #

啟用或停用查詢規劃器使用巢狀迴圈聯結方案。完全抑制巢狀迴圈聯結是不可能的,但關閉此變數會阻止規劃器在有其他方法可用時使用它。預設值為 on

enable_parallel_append (boolean) #

啟用或停用查詢規劃器使用平行感知附加 (parallel-aware append) 方案類型。預設值為 on

enable_parallel_hash (boolean) #

啟用或停用查詢規劃器使用具有平行雜湊的雜湊聯結方案類型。如果未同時啟用雜湊聯結方案,則無效。預設值為 on

enable_partition_pruning (boolean) #

啟用或停用查詢規劃器從查詢方案中消除分割資料表的分割區的能力。這也控制規劃器產生查詢方案的能力,該方案允許查詢執行器在查詢執行期間移除(忽略)分割區。預設值為 on。詳細資訊請參閱第 5.12.4 節

enable_partitionwise_join (boolean) #

啟用或停用查詢規劃器使用按分割區聯結 (partitionwise join),這允許透過聯結匹配的分割區來執行分割資料表之間的聯結。按分割區聯結目前僅在聯結條件包含所有分割區鍵時才適用,這些分割區鍵必須具有相同的資料類型,並且具有一對一匹配的子分割區集。啟用此設定後,最終方案中受 work_mem 限制記憶體使用量的節點數量可能會根據正在掃描的分割區數量線性增加。這可能會導致查詢執行期間整體記憶體消耗的大幅增加。查詢規劃在記憶體和 CPU 方面也會變得更加昂貴。預設值為 off

enable_partitionwise_aggregate (boolean) #

啟用或停用查詢規劃器使用按分割區分組或彙總 (partitionwise grouping or aggregation),這允許對每個分割區分別執行分割資料表上的分組或彙總。如果 GROUP BY 子句不包含分割區鍵,則只能在每個分割區的基礎上執行部分彙總,並且必須稍後執行最終確定。啟用此設定後,最終方案中受 work_mem 限制記憶體使用量的節點數量可能會根據正在掃描的分割區數量線性增加。這可能會導致查詢執行期間整體記憶體消耗的大幅增加。查詢規劃在記憶體和 CPU 方面也會變得更加昂貴。預設值為 off

enable_presorted_aggregate (boolean) #

控制查詢規劃器是否產生一個方案,該方案將提供以查詢 ORDER BY / DISTINCT 彙總函數所需的順序預先排序的列。 停用後,查詢規劃器將產生一個方案,該方案總是要求執行器在執行包含 ORDER BYDISTINCT 子句的每個彙總函數的彙總之前執行排序。 啟用後,規劃器將嘗試產生一個更有效率的方案,該方案為彙總函數提供以它們需要進行彙總的順序預先排序的輸入。 預設值為 on

enable_seqscan (boolean) #

啟用或停用查詢規劃器使用循序掃描方案類型。完全抑制循序掃描是不可能的,但關閉此變數會阻止規劃器在有其他方法可用時使用它。預設值為 on

enable_sort (boolean) #

啟用或停用查詢規劃器使用明確的排序步驟。完全抑制明確排序是不可能的,但關閉此變數會阻止規劃器在有其他方法可用時使用它。預設值為 on

enable_tidscan (boolean) #

啟用或停用查詢規劃器使用TID掃描方案類型。預設值為 on

19.7.2. 規劃器成本常數 #

本節中描述的 成本 變數是以任意尺度測量的。只有它們的相對值才重要,因此將它們全部按相同因子放大或縮小不會導致規劃器的選擇發生變化。預設情況下,這些成本變數基於循序頁面提取的成本;也就是說,seq_page_cost 通常設定為 1.0,而其他成本變數則參考該值設定。但如果您願意,可以使用不同的尺度,例如特定機器上的實際執行時間(以毫秒為單位)。

注意

遺憾的是,沒有明確定義的方法來確定成本變數的理想值。最好將它們視為特定安裝將接收的整個查詢組合的平均值。這意味著僅僅根據幾個實驗來更改它們是非常危險的。

seq_page_cost (floating point) #

設定規劃器對磁碟頁面提取成本的估計值,該提取是連續提取系列的一部分。預設值為 1.0。對於特定表空間中的表和索引,可以透過設定同名的表空間參數來覆寫此值(請參閱ALTER TABLESPACE)。

random_page_cost (floating point) #

設定規劃器對非循序提取的磁碟頁面成本的估計值。預設值為 4.0。對於特定表空間中的表和索引,可以透過設定同名的表空間參數來覆寫此值(請參閱ALTER TABLESPACE)。

相對於 seq_page_cost 降低此值將導致系統偏好索引掃描;提高此值將使索引掃描看起來相對更昂貴。您可以一起提高或降低這兩個值,以更改磁碟 I/O 成本相對於 CPU 成本的重要性,CPU 成本由以下參數描述。

對機械磁碟儲存體的隨機存取通常比循序存取昂貴得多,是後者的四倍以上。但是,由於假設大多數對磁碟的隨機存取(例如索引讀取)都在快取中,因此使用較低的預設值 (4.0)。預設值可以認為是將隨機存取建模為比循序存取慢 40 倍,同時預期 90% 的隨機讀取會被快取。

如果您認為 90% 快取率對於您的工作負載是不正確的假設,您可以增加 random_page_cost 以更好地反映隨機儲存讀取的真實成本。 相應地,如果您的資料可能完全在快取中(例如當資料庫小於伺服器總記憶體時),則降低 random_page_cost 可能是合適的。相對於循序讀取,具有較低隨機讀取成本的儲存體(例如固態硬碟)也可以使用較低的 random_page_cost 值(例如 1.1)更好地建模。

提示

雖然系統允許您將 random_page_cost 設定為小於 seq_page_cost,但這樣做在物理上沒有意義。但是,如果資料庫完全快取在 RAM 中,則將它們設定為相等是有意義的,因為在這種情況下,非循序存取頁面沒有任何懲罰。 此外,在大量快取的資料庫中,您應該相對於 CPU 參數降低這兩個值,因為提取已在 RAM 中的頁面的成本遠小於通常情況。

cpu_tuple_cost (floating point) #

設定規劃器對查詢期間處理每列資料成本的估計值。預設值為 0.01。

cpu_index_tuple_cost (floating point) #

設定規劃器對索引掃描期間處理每個索引條目成本的估計值。預設值為 0.005。

cpu_operator_cost (floating point) #

設定規劃器對查詢期間執行每個運算子或函式成本的估計值。預設值為 0.0025。

parallel_setup_cost (floating point) #

設定規劃器對啟動平行工作程序成本的估計值。預設值為 1000。

parallel_tuple_cost (floating point) #

設定規劃器對從平行工作程序傳輸一個 tuple 到另一個程序成本的估計值。預設值為 0.1。

min_parallel_table_scan_size (integer) #

設定考慮進行平行掃描所需的最小表資料量。對於平行循序掃描,掃描的表資料量始終等於表的大小,但當使用索引時,掃描的表資料量通常會較少。如果未指定單位,則此值以區塊為單位,即 BLCKSZ 位元組,通常為 8kB。預設值為 8 MB (8MB)。

min_parallel_index_scan_size (integer) #

設定考慮進行平行掃描所需的最小索引資料量。請注意,平行索引掃描通常不會觸及整個索引;相關的是規劃器認為掃描實際將觸及的頁面數。此參數也用於決定特定索引是否可以參與平行 vacuum。請參閱VACUUM。如果未指定單位,則此值以區塊為單位,即 BLCKSZ 位元組,通常為 8kB。預設值為 512 KB (512kB)。

effective_cache_size (integer) #

設定規劃器對單一查詢可用的有效磁碟快取大小的假設。這會被納入使用索引成本的估算中;較高的值會使索引掃描更有可能被使用,而較低的值會使循序掃描更有可能被使用。設定此參數時,您應同時考慮 PostgreSQL 的共享緩衝區以及核心磁碟快取中將用於 PostgreSQL 資料檔案的部分,儘管某些資料可能同時存在於這兩個地方。此外,還要考慮到不同表格上預期的並行查詢數量,因為它們必須共享可用空間。此參數對 PostgreSQL 分配的共享記憶體大小沒有影響,也不會保留核心磁碟快取;它僅用於估算目的。系統也不會假設資料在查詢之間保留在磁碟快取中。如果指定此值時沒有單位,則將其視為區塊,即 BLCKSZ 位元組,通常為 8kB。預設值為 4 GB (4GB)。(如果 BLCKSZ 不是 8kB,則預設值會與其成比例縮放。)

jit_above_cost (floating point) #

設定啟用 JIT 編譯的查詢成本上限(如果已啟用,請參閱第 30 章)。執行JIT會增加規劃時間,但可以加速查詢執行。將此值設定為 -1 會停用 JIT 編譯。預設值為 100000

jit_inline_above_cost (floating point) #

設定 JIT 編譯嘗試內聯函數和運算符的查詢成本上限。內聯會增加規劃時間,但可以提高執行速度。將此值設定為小於 jit_above_cost 是沒有意義的。將此值設定為 -1 會停用內聯。預設值為 500000

jit_optimize_above_cost (floating point) #

設定 JIT 編譯應用昂貴優化的查詢成本上限。這種優化會增加規劃時間,但可以提高執行速度。將此值設定為小於 jit_above_cost 是沒有意義的,並且將其設定為大於 jit_inline_above_cost 也可能沒有好處。將此值設定為 -1 會停用昂貴的優化。預設值為 500000

19.7.3. 基因查詢最佳化器 #

基因查詢最佳化器 (GEQO) 是一種使用啟發式搜尋進行查詢規劃的演算法。這減少了複雜查詢(連接許多關係的查詢)的規劃時間,但代價是產生的計劃有時不如正常的詳盡搜尋演算法找到的計劃。有關更多資訊,請參閱第 60 章

geqo (boolean) #

啟用或停用基因查詢最佳化。預設為開啟。通常最好不要在生產環境中將其關閉;geqo_threshold 變數提供了對 GEQO 更精細的控制。

geqo_threshold (integer) #

使用基因查詢最佳化來規劃至少包含這麼多 FROM 項目的查詢。(請注意,FULL OUTER JOIN 結構只算作一個 FROM 項目。)預設值為 12。對於較簡單的查詢,通常最好使用常規的詳盡搜尋規劃器,但對於包含許多表格的查詢,詳盡搜尋需要太長時間,通常比執行次佳計劃的懲罰時間還要長。因此,查詢大小的閾值是管理 GEQO 使用的一種便捷方式。

geqo_effort (integer) #

控制 GEQO 中規劃時間和查詢計劃品質之間的權衡。此變數必須是 1 到 10 範圍內的整數。預設值為 5。較大的值會增加執行查詢規劃所花費的時間,但也會增加選擇高效查詢計劃的可能性。

geqo_effort 實際上並不會直接執行任何操作;它僅用於計算影響 GEQO 行為的其他變數(如下所述)的預設值。如果您願意,您可以改為手動設定其他參數。

geqo_pool_size (integer) #

控制 GEQO 使用的池大小,即基因族群中的個體數量。它必須至少為 2,且有用的值通常為 100 到 1000。如果將其設定為零(預設設定),則會根據 geqo_effort 和查詢中的表格數量選擇合適的值。

geqo_generations (integer) #

控制 GEQO 使用的世代數,即演算法的迭代次數。它必須至少為 1,且有用的值與池大小的範圍相同。如果將其設定為零(預設設定),則會根據 geqo_pool_size 選擇合適的值。

geqo_selection_bias (floating point) #

控制 GEQO 使用的選擇偏差。選擇偏差是族群內的選擇壓力。值可以從 1.50 到 2.00;後者為預設值。

geqo_seed (floating point) #

控制 GEQO 使用的亂數產生器的初始值,以選擇透過聯結順序搜尋空間的隨機路徑。該值的範圍可以從零(預設值)到一。改變該值會改變探索的聯結路徑集合,並可能導致找到更好或更差的最佳路徑。

19.7.4. 其他規劃器選項 #

default_statistics_target (integer) #

設定表格欄位的預設統計目標,這些欄位沒有透過 ALTER TABLE SET STATISTICS 設定特定的欄位目標。較大的數值會增加執行 ANALYZE 所需的時間,但可能會改善查詢規劃器估算的品質。預設值為 100。關於 PostgreSQL 查詢規劃器使用統計資訊的更多資訊,請參閱 第 14.2 節

constraint_exclusion (enum) #

控制查詢規劃器使用表格約束來優化查詢。 constraint_exclusion 允許的值為 on(檢查所有表格的約束)、off(永不檢查約束)和 partition(僅檢查繼承子表格和 UNION ALL 子查詢的約束)。 partition 是預設設定。它通常與傳統的繼承樹一起使用,以提高效能。

當此參數允許特定表格時,規劃器會將查詢條件與表格的 CHECK 約束進行比較,並省略掃描與約束條件相矛盾的表格。例如

CREATE TABLE parent(key integer, ...);
CREATE TABLE child1000(check (key between 1000 and 1999)) INHERITS(parent);
CREATE TABLE child2000(check (key between 2000 and 2999)) INHERITS(parent);
...
SELECT * FROM parent WHERE key = 2400;

啟用約束排除後,此 SELECT 將完全不會掃描 child1000,從而提高效能。

目前,預設情況下,約束排除僅適用於通常用於透過繼承樹實現表格分割的情況。 為所有表格啟用它會增加額外的規劃開銷,這在簡單查詢中非常明顯,並且通常不會為簡單查詢帶來任何好處。 如果您沒有使用傳統繼承分割的表格,您可能更喜歡完全關閉它。(請注意,分割表格的等效功能由單獨的參數控制,即 enable_partition_pruning。)

有關使用約束排除來實現分割的更多資訊,請參閱 第 5.12.5 節

cursor_tuple_fraction (floating point) #

設定規劃器對將要檢索的游標列數的估計比例。 預設值為 0.1。 此設定的較小值會使規劃器傾向於對游標使用 快速啟動 計劃,這將快速檢索前幾行,但可能需要很長時間才能提取所有行。 較大的值會更加強調總估計時間。 在最大設定 1.0 時,游標的規劃方式與常規查詢完全相同,僅考慮總估計時間,而不考慮可能多快交付第一行。

from_collapse_limit (integer) #

如果結果的 FROM 列表的項目不超過此數量,則規劃器會將子查詢合併到上層查詢中。 較小的值會減少規劃時間,但可能會產生較差的查詢計劃。 預設值為 8。 更多資訊請參閱 第 14.3 節

將此值設定為 geqo_threshold 或更大可能會觸發 GEQO 規劃器的使用,導致非最佳計劃。 請參閱 第 19.7.3 節

jit (boolean) #

決定是否JIT如果可用,則 PostgreSQL 可以使用編譯 (請參閱 第 30 章)。 預設值為 on

join_collapse_limit (integer) #

只要列表中的項目不超過此數量,規劃器就會將顯式 JOIN 建構(除了 FULL JOINs)重寫為 FROM 項目列表。 較小的值會減少規劃時間,但可能會產生較差的查詢計劃。

預設情況下,此變數設定為與 from_collapse_limit 相同,這適用於大多數用途。 將其設定為 1 可以防止任何顯式 JOIN 的重新排序。 因此,查詢中指定的顯式聯接順序將是關係聯接的實際順序。 由於查詢規劃器並不總是選擇最佳聯接順序,因此高級用戶可以選擇臨時將此變數設定為 1,然後顯式指定他們想要的聯接順序。 更多資訊請參閱 第 14.3 節

將此值設定為 geqo_threshold 或更大可能會觸發 GEQO 規劃器的使用,導致非最佳計劃。 請參閱 第 19.7.3 節

plan_cache_mode (enum) #

預備語句(顯式預備或隱式產生,例如由 PL/pgSQL 產生)可以使用自定義或通用計劃執行。 自定義計劃是針對每次執行使用其特定參數值集重新製作的,而通用計劃不依賴於參數值,並且可以在執行之間重複使用。 因此,使用通用計劃可以節省規劃時間,但如果理想計劃在很大程度上取決於參數值,則通用計劃可能效率低下。 通常會自動做出這些選項之間的選擇,但可以使用 plan_cache_mode 覆蓋它。 允許的值為 auto(預設)、force_custom_planforce_generic_plan。 在要執行快取計劃時,而不是在預備計劃時,會考慮此設定。 更多資訊請參閱 PREPARE

recursive_worktable_factor (floating point) #

設定規劃器對 遞迴查詢的工作表格平均大小的估計,即查詢初始非遞迴項估計大小的倍數。 這有助於規劃器選擇最合適的方法將工作表格聯接到查詢的其他表格。 預設值為 10.0。 當遞迴從一個步驟到下一步的 扇出 較低時,例如在最短路徑查詢中,較小的值(例如 1.0)可能會有所幫助。 圖形分析查詢可能會受益於大於預設值的值。

提交更正

如果您在文件中發現任何不正確、與特定功能的經驗不符或需要進一步澄清的內容,請使用此表格回報文件問題。