PolarDB PostgreSQL版支持彈性跨機并行查詢 (elastic Parallel Query,簡稱ePQ),能夠高效支持輕量級的分析型查詢,滿足用戶日漸需要的HTAP能力。
簡介
當查詢使用ePQ特性時,PolarDB PostgreSQL版將通過ePQ優化器,生成能夠被多個計算節點并行執行的執行計劃。ePQ的執行引擎將在多個計算節點上協調執行該計劃,同時利用多個節點的CPU、內存、I/O帶寬來掃描、計算數據。
您可以通過GUC參數動態調整參與ePQ并行執行的計算節點 (Scale Out),以及節點上的單機并行度 (Scale Up),從而實現Serverless彈性擴展。
ePQ善于解決復雜、執行時間長的OLAP長查詢,不適用于簡單、執行時間短的OLTP短查詢。對于短查詢而言,計算節點之間建立連接、數據交換、銷毀連接的開銷反而會引發查詢性能的回退。PolarDB PostgreSQL版支持根據表的大小或執行計劃的代價來控制對查詢使用ePQ還是單機執行,從而在查詢不同大小的表和執行不同代價的計劃時,能夠選擇性能更好的查詢執行方式。
關于更多ePQ的原理介紹和性能數據,請參見PolarDB PostgreSQL版:ePQ架構詳解。
一鍵開啟ePQ功能
如果當前有張表t1
,可以通過以下命令一鍵開啟ePQ功能。如輸出所示,如果計劃中出現PolarDB PX Optimizer
,則說明ePQ已經生效。
SET polar_enable_px = 1;
EXPLAIN SELECT * FROM t1;
QUERY PLAN
-------------------------------------------------------------------------------
PX Coordinator 6:1 (slice1; segments: 6) (cost=0.00..431.00 rows=1 width=8)
-> Partial Seq Scan on t1 (cost=0.00..431.00 rows=1 width=8)
Optimizer: PolarDB PX Optimizer
(3 rows)
SELECT * FROM t1;
GUC參數說明
參數 | 說明 |
polar_enable_px | 用于開啟或關閉ePQ功能。取值如下:
說明 當參數開啟后,查詢將會優先進入ePQ優化器中,產生能夠被并行執行的計。此外,所有ePQ相關的GUC參數將會開始生效。 |
polar_px_nodes | 用于指定參與ePQ的計算節點名稱。默認值為空,表示所有只讀節點都參與ePQ并行執行: 如果只想配置特定的只讀節點參與ePQ并行執行,可以通過以下方法獲取只讀節點的名稱:
然后將得到的節點名稱以逗號分隔,設置polar_px_nodes:
|
polar_px_dop_per_node | 用于設置當前會話中每個計算節點上參與ePQ并行執行的工作進程數。默認值為3。 說明 一般最佳實踐值是當前節點CPU核數的一半。如果當前節點的CPU負載較高,可以遞減該參數,直到CPU占用率不超過 80%。當查詢性能不佳時,也可以遞增該參數,但不要使CPU占用率超過80%,否則可能會拖慢系統的其它后臺進程。 |
polar_px_max_workers_number | 用于設置每個計算節點上最多可以同時存在的ePQ工作進程數量。默認值為30。 說明 如果超出這個限制時,查詢將會出錯:
此時,可以增大該參數,以避免出現類似的報錯。如果該參數設置得過大,也有可能會使節點上的進程數量過多,增大了OOM的風險。 |
polar_px_wait_lock_timeout | 用于設置ePQ進程阻塞其它進程的最大時間。默認值為1800000毫秒(半小時)。 ePQ進程通常是只讀查詢,會對進行查詢的表加共享鎖。而用戶的部分DDL需要對表加排他鎖,從而因鎖沖突而被ePQ進程阻塞,在阻塞到該參數所指定的毫秒數后,ePQ查詢將會被取消,為執行DDL的進程讓路。 由于ePQ通常被用于執行較為耗時的分析型查詢,因此 |
synchronous_commit | 用于確保ePQ并行查詢的數據一致性。取值如下:
|
polar_px_min_pg_plan_cost | 表示啟用ePQ的執行計劃代價最小值,取值范圍:0~999999999999,默認值為50000。單機執行計劃代價低于該閾值的查詢將不會使用ePQ。 |
polar_px_min_table_scan_size | 表示啟用ePQ的最小表大小,取值范圍:0~2147483647,默認值為100 MB。當查詢中引用的所有表的大小都低于該閾值時,將不會使用ePQ。 |
polar_px_force_use | 表示是否強制使用ePQ進行查詢,取值如下: on:強制使用ePQ進行查詢。 off(默認):不強制使用ePQ進行查詢。 |
最佳實踐
允許特定的表使用ePQ
如果只想針對特定表執行ePQ,可以開啟polar_px_enable_check_workers
參數。同時對需要執行ePQ的表顯式設置px_workers
選項。
ALTER TABLE t1 SET (px_workers = 1);
px_workers
的取值如下:
-1
:禁止對該表使用ePQ并行執行。0
:默認狀態,對該表忽略ePQ并行執行。1
:允許對該表使用ePQ并行執行。
開啟ePQ功能
全局級別
在PolarDB控制臺上設置polar_enable_px
參數為on
,即可全局啟用ePQ功能,無論是OLTP查詢還是OLAP查詢,都將默認使用ePQ。
使用如下示例查看執行計劃。如果計劃中出現PolarDB PX Optimizer
,則說明ePQ已經生效:
=> EXPLAIN SELECT * FROM t1;
QUERY PLAN
-------------------------------------------------------------------------------
PX Coordinator 6:1 (slice1; segments: 6) (cost=0.00..431.00 rows=1 width=8)
-> Partial Seq Scan on t1 (cost=0.00..431.00 rows=1 width=8)
Optimizer: PolarDB PX Optimizer
(3 rows)
會話級別
在會話內設置polar_enable_px
參數為ON
,使當前會話內的所有查詢默認使用ePQ:
SET polar_enable_px = ON;
數據庫級別/用戶級別
在全局級別或會話級別啟用ePQ后,會話內的所有的查詢都會優先使用ePQ。從最佳實踐的角度來說,ePQ更適用于需要進行大量OLAP負載的長查詢,而不適用于OLTP短查詢。對于短查詢來說,ePQ在計算節點間的建立連接、數據交換、銷毀連接的開銷將會引發查詢性能的回退。
如果在業務設計上需要使用到ePQ,那么可以將業務中的分析型SQL提取出來,使用一個特定的數據庫來進行ePQ查詢:
ALTER DATABASE ap_database SET polar_enable_px = ON;
或使用某個特定的賬戶,專門用來執行分析型的SQL:
ALTER ROLE ap_role SET polar_enable_px = ON;
查詢級別
如果只想對一個會話內的某幾條特定查詢(例如,夜間報表業務)使用ePQ,可以借助pg_hint_plan
插件,通過SQL Hint對特定查詢啟用ePQ。為使SQL Hint生效,需要確保pg_hint_plan
插件已經被添加到GUC參數shared_preload_libraries
中。
在查詢前添加/*+ PX() */
表示對該查詢使用ePQ:
=> /*+ PX() */ EXPLAIN SELECT * FROM t1;
QUERY PLAN
----------------------------------------------------------------------------------
PX Coordinator 6:1 (slice1; segments: 6) (cost=0.00..431.03 rows=1000 width=8)
-> Partial Seq Scan on t1 (cost=0.00..431.00 rows=167 width=8)
Optimizer: PolarDB PX Optimizer
(3 rows)
在查詢前添加/*+ NoPX() */
表示對該查詢不使用ePQ:
=> /*+ NoPX() */ EXPLAIN SELECT * FROM t1;
QUERY PLAN
------------------------------------------------------
Seq Scan on t1 (cost=0.00..15.00 rows=1000 width=8)
(1 row)
在查詢前添加/*+ PX(N) */
表示以N
作為單節點并行度使用ePQ。例如,N
取值為6
:
=> /*+ PX(6) */ EXPLAIN SELECT * FROM t1;
QUERY PLAN
------------------------------------------------------------------------------------
PX Coordinator 12:1 (slice1; segments: 12) (cost=0.00..431.02 rows=1000 width=8)
-> Partial Seq Scan on t1 (cost=0.00..431.00 rows=84 width=8)
Optimizer: PolarDB PX Optimizer
(3 rows)