

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# RDS for PostgreSQL 中平行查詢的最佳實務
<a name="PostgreSQL.ParallelQueries"></a>

平行查詢執行是 PostgreSQL 的一項功能，可讓單一 SQL 查詢分割為由多個背景工作者程序同時處理的較小任務。PostgreSQL 可以跨多個 CPU 核心分配部分的查詢，例如掃描、聯結、彙總或排序，而不是完全在單一後端程序中執行查詢。*領導者程序*會協調此執行，並從*平行工作者*收集結果。

不過，對於大多數生產工作負載，特別是高並行 OLTP 系統，我們建議停用自動平行查詢執行。雖然平行處理可以加速分析或報告工作負載中大型資料集的查詢，但它帶來的重大風險通常超過忙碌生產環境中的優勢。

平行執行也會帶來大量的額外負荷。每個平行工作者都是完整的 PostgreSQL 後端程序，這需要程序偽造 （複製記憶體結構和初始化程序狀態） 和身分驗證 （從您的`max_connections`限制使用連線插槽）。每個工作者也會使用自己的記憶體，包括`work_mem`用於排序和雜湊操作，每個查詢有多個工作者，記憶體用量會快速增加 （例如，4 個工作者 × 64MB `work_mem` = 每個查詢 256MB)。因此，平行查詢可能會耗用比單一程序查詢更多的系統資源。如果未正確調校， 它們可能會導致 CPU 飽和 （多個工作者壓倒可用的處理容量）， 增加內容切換 （作業系統經常在許多工作者程序之間切換， 新增額外負荷並降低輸送量）、 或 連線耗盡 （因為每個平行工作者都會使用連線插槽， 具有 4 個工作者的單一查詢總共使用 5 個連線， 1 個領導者 \$1 4 個工作者， 可在高並行下快速耗盡連線集區， 防止新的用戶端連線並導致應用程式失敗）。在高並行工作負載中，這些問題特別嚴重，其中多個查詢可能會同時嘗試平行執行。

PostgreSQL 會根據成本估算決定是否使用平行處理。在某些情況下，規劃器可能會自動切換到平行計劃，即使實際上並不理想，它看起來更便宜。如果索引統計資料已過期，或者如果膨脹使循序掃描看起來比索引查詢更具吸引力，則可能會發生這種情況。由於這種行為，自動平行計畫有時可能會在查詢效能或系統穩定性中引入迴歸。

若要從 RDS for PostgreSQL 的平行查詢中獲得最大效益，請務必根據您的工作負載進行測試和調校、監控系統影響，以及停用自動平行計劃選擇，以有利於查詢層級控制。

## 組態參數
<a name="PostgreSQL.ParallelQueries.ConfigurationParameters"></a>

PostgreSQL 使用數個參數來控制平行查詢的行為和可用性。了解和調校這些對於實現可預測效能至關重要：


| 參數 | 描述 | 預設 | 
| --- | --- | --- | 
| max\$1parallel\$1workers | 可以執行的背景工作者程序總數上限 | GREATEST(\$1DBInstanceVCPU/2,8) | 
| max\$1parallel\$1workers\$1per\$1gather | 每個查詢計劃節點的工作者數量上限 （例如，每個 Gather) | 2 | 
| parallel\$1setup\$1cost | 新增啟動平行查詢基礎設施的規劃器成本 | 1000 | 
| parallel\$1tuple\$1cost | 在平行模式下處理的每元組成本 （影響規劃器決策） | 0.1 | 
| force\$1parallel\$1mode | 強制規劃器測試平行計劃 (off、on、regress) | off | 

### 重要考量事項
<a name="PostgreSQL.ParallelQueries.ConfigurationParameters.KeyConsiderations"></a>
+ `max_parallel_workers` 控制平行工作者的總集區。如果設定過低，某些查詢可能會回復到序列執行。
+ `max_parallel_workers_per_gather` 會影響單一查詢可以使用的工作者數量。較高的值會增加並行，但也會增加資源用量。
+ `parallel_setup_cost` 和 `parallel_tuple_cost`會影響規劃器的成本模型。降低這些值可能會讓平行計劃更容易被選擇。
+ `force_parallel_mode` 適用於測試，但除非必要，否則不應用於生產環境。

**注意**  
參數的預設值`max_parallel_workers`會根據執行個體大小使用公式 動態計算`GREATEST($DBInstanceVCPU/2, 8)`。這表示當您將 DB 執行個體擴展到具有更多 vCPUs較大運算大小時，可用的平行工作者數量上限會自動增加。因此，先前連續執行或具有有限平行處理的查詢可能會在擴展操作後突然利用更多平行工作者，這可能會導致連線用量、CPU 使用率和記憶體耗用量意外增加。請務必監控任何運算擴展事件之後的平行查詢行為`max_parallel_workers_per_gather`，並視需要調整以維持可預測的資源用量。

## 識別平行查詢用量
<a name="PostgreSQL.ParallelQueries.IdentifyUsage"></a>

查詢可能會根據資料分佈或統計資料轉換為平行計畫。例如：

```
SELECT count(*) FROM customers WHERE last_login < now() - interval '6 months';
```

此查詢可能會針對最近資料使用 索引，但切換到針對歷史資料的平行循序掃描。

您可以透過載入 `auto_explain`模組來記錄查詢執行計畫。若要進一步了解，請參閱 AWS 知識中心的[記錄查詢的執行計畫](https://aws.amazon.com/premiumsupport/knowledge-center/rds-postgresql-tune-query-performance/#)。



您可以監控 [CloudWatch Database Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Database-Insights-Database-Instance-Dashboard.html) 的平行查詢相關等待事件。若要進一步了解平行查詢相關的等待事件，請執行 [IPC：平行等待事件](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/apg-ipc-parallel.html)

從 PostgreSQL 第 18 版，您可以使用 [https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW)和 中的新資料欄來監控平行工作者活動[https://www.postgresql.org/docs/current/pgstatstatements.html](https://www.postgresql.org/docs/current/pgstatstatements.html)：
+ `parallel_workers_to_launch`：計劃啟動的平行工作者數量
+ `parallel_workers_launched`：實際啟動的平行工作者數量

這些指標有助於識別計劃和實際平行處理之間的差異，這可能表示資源限制或組態問題。使用下列查詢來監控平行執行：

對於資料庫層級平行工作者指標：

```
SELECT datname, parallel_workers_to_launch, parallel_workers_launched
FROM pg_stat_database
WHERE datname = current_database();
```

對於查詢層級平行工作者指標

```
SELECT query, parallel_workers_to_launch, parallel_workers_launched
FROM pg_stat_statements
ORDER BY parallel_workers_launched;
```

## 如何控制平行處理
<a name="PostgreSQL.ParallelQueries.ControlParallelism"></a>

有多種方法可以控制查詢平行處理，每個都針對不同的案例和需求而設計。

若要全域停用自動平行處理，請[修改參數群組](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.Modifying.html)以設定：

```
max_parallel_workers_per_gather = 0;
```

對於持久性的使用者特定設定，ALTER ROLE 命令提供設定參數的方法，這些參數將套用至特定使用者未來的所有工作階段。

例如：

`ALTER ROLE username SET max_parallel_workers_per_gather = 4;` 確保每次此使用者連線到資料庫時，其工作階段都會在需要時使用此平行工作者設定。

您可以使用 SET 命令來達成工作階段層級控制，該命令會修改目前資料庫工作階段期間的參數。當您需要暫時調整設定，而不會影響其他使用者或未來的工作階段時，這特別有用。一旦設定，這些參數會保持有效，直到明確重設或工作階段結束為止。命令非常簡單：

```
SET max_parallel_workers_per_gather = 4;
-- Run your queries
RESET max_parallel_workers_per_gather;
```

對於更精細的控制，SET LOCAL 可讓您修改單一交易的參數。當您需要調整交易中特定查詢集的設定時，這很理想，之後設定會自動回復到其先前的值。此方法有助於防止對相同工作階段中的其他操作產生意外影響。

## 診斷平行查詢行為
<a name="PostgreSQL.ParallelQueries.Diagnosing"></a>

使用 `EXPLAIN (ANALYZE, VERBOSE)`確認查詢是否使用平行執行：
+ 尋找節點，例如 `Gather`、 `Gather Merge`或 `Parallel Seq Scan`。
+ 比較具有和沒有平行處理的計劃。

若要暫時停用平行處理以進行比較：

```
SET max_parallel_workers_per_gather = 0;
EXPLAIN ANALYZE <your_query>;
RESET max_parallel_workers_per_gather;
```