15.2. 何時會用到并行查詢?
有幾種設定會導緻查詢規劃器在任何情況下都不生成并行查詢計劃。為了讓并行查詢計劃能夠被生成,必須配置好下列設定。
- max_parallel_workers_per_gather 必須被設定為大于零的值。這是一種特殊情況,更加普遍的原則是所用的工作者數量不能超過
所配置的數量。max_parallel_workers_per_gather
- dynamic_shared_memory_type 必須被設定為除
之外的值。并行查詢要求動态共享記憶體以便在合作的程序之間傳遞資料。none
此外,系統一定不能運作在單使用者模式下。因為在單使用者模式下,整個資料庫系統運作在單個程序中,沒有背景工作者程序可用。
如果下面的任一條件為真,即便對一個給定查詢通常可以産生并行查詢計劃,規劃器都不會為它産生并行查詢計劃:
- 查詢要寫任何資料或者鎖定任何資料庫行。如果一個查詢在頂層或者 CTE 中包含了資料修改操作,那麼不會為該查詢産生并行計劃。這是目前實作的一個限制,未來的版本中可能會有所改進。
- 查詢可能在執行過程中被暫停。隻要在系統認為可能發生部分或者增量式執行,就不會産生并行計劃。例如:用 DECLARE CURSOR 建立的遊标将永遠不會使用并行計劃。類似地,一個
形式的 PL/pgSQL 循環也永遠 不會使用并行計劃,因為當并行查詢進行時,并行查詢系統無法驗證循環中的代碼執行起來是安全的。FOR x IN query LOOP .. END LOOP
- 使用了任何被标記為
的函數的查詢。大多數系統定義的函數都被标記為PARALLEL UNSAFE
,但是使用者定義的函數預設被标記為PARALLEL SAFE
。參見 第 15.4 節 中的讨論。PARALLEL UNSAFE
- 該查詢運作在另一個已經存在的并行查詢内部。例如,如果一個被并行查詢調用的函數自己發出一個 SQL 查詢,那麼該查詢将不會使用并行計劃。這是目前實作的一個限制,但是或許不值得移除這個限制,因為它會導緻單個查詢使用大量的程序。
- 事務隔離級别是可串行化。這是目前實作的一個限制。
即使對于一個特定的查詢已經産生了并行查詢計劃,在一些情況下執行時也不會并行執行該計劃。如果發生這種情況,那麼上司者将會自己執行該計劃在
Gather
節點之下的部分,就好像
Gather
節點不存在一樣。上述情況将在滿足下面的任一條件時發生:
- 因為背景工作者程序的總數不能超過 max_worker_processes ,導緻不能得到背景工作者程序。
- 由于為并行查詢而啟動的背景工作者總數不能超過 max_parallel_workers ,是以無法獲得背景工作者。
- 用戶端發送了一個執行消息,并且消息中要求取元組的數量不為零。執行消息可見 擴充查詢協定 中的讨論。因為 libpq 目前沒有提供方法來發送這種消息,是以這種情況隻可能發生在不依賴 libpq 的用戶端中。如果這種情況經常發生,那在它可能發生的會話中将 設定為0是一個很好的主意,這樣可以避免産生連續運作時次優的查詢計劃。
- 準備好的語句是使用
語句執行的。 此構造将本來隻是隻讀操作的内容轉換為讀寫操作,使其不适合并行查詢。CREATE TABLE .. AS EXECUTE ..
- 事務隔離級别是可串行化。這種情況通常不會出現,因為當事務隔離級别是可串行化時不會産生并行查詢計劃。不過,如果在産生計劃之後并且在執行計劃之前把事務隔離級别改成可串行化,這種情況就有可能發生。
本文轉自PostgreSQL中文社群,原文連結: