PolarDB PostgreSQL版(兼容Oracle)支持使用跨機并行查詢功能進行分析型查詢,實現一定的HTAP能力。本文介紹如何使用跨機并行查詢,提升分析型查詢的性能。
原理介紹
當一條查詢請求在查詢協調節點上被執行跨機并行查詢時,該查詢產生的執行計劃會被分片路由至各個執行節點,每個執行節點將會執行各自的分片計劃,并將分片的查詢結果匯總至查詢協調節點??梢苑Q查詢協調節點為QC(Query Coordinator)節點,稱分片計劃的執行節點為PX(Parallel Execution)節點。
如上圖所示,RO1為QC節點,它接收了一條查詢輸入請求,并將查詢計劃分片路由至RO2、RO3、RO4三個PX節點。每個PX節點將會針對各自接收到的分片計劃,最終從PolarFS共享存儲上讀取到各自所需的數據塊,由執行節點執行完成相應的分片計劃,并將執行結果返回為QC節點,QC節點匯總后返回查詢結果。
注意事項
由于跨機并行查詢功能需使用多個只讀節點資源,因此只適用于低頻次的分析型查詢。
細粒度使用方式
- 系統粒度:通過參數控制所有session所有查詢是否開啟跨機并行查詢。
- 會話粒度:通過alter session或session級別的GUC參數控制當前session是否開啟跨機并行查詢。
- 查詢粒度:通過hint指定具體查詢是否開啟跨機并行查詢。
參數說明
默認情況下,PolarDB PostgreSQL版(兼容Oracle)不開啟跨機并行查詢功能。若您需要使用此功能,請使用如下參數:
參數 | 說明 |
---|---|
polar_cluster_map | 用于查詢當前PolarDB PostgreSQL版(兼容Oracle)所有只讀節點的名稱。該參數不可配置。當您新增一個只讀節點時,該參數會進行更新。 說明 只有內核小版本(V1.1.20)(發布時間:2022年1月)之前創建的集群才包含該參數。 |
polar_px_nodes | 指定參與跨機并行查詢的只讀節點。默認為空,表示所有只讀節點都參與??膳渲脼橹付ü濣c參與跨機并行查詢,以逗號分隔。例如:
|
polar_px_enable_replay_wait | PolarDB PostgreSQL版(兼容Oracle)的主節點與只讀節點存在一定程度的延遲,當主節點執行DDL語句(例如CREATE TABLE),只讀節點需要耗時回放該DDL日志后才可見新創建的表。當設置polar_px_enable_replay_wait 為on后,跨機并行查詢啟用強一致性,當前發起的跨機并行查詢請求路由到只讀節點上執行時,需要只讀節點回放到該查詢請求前最近的一條日志后,才會執行查詢請求。該參數默認為off,即關閉強一致性,在數據庫主備日志延遲較高時,不保證只讀節點可以讀到最近的DDL記錄。您可配置 該參數可以指定數據庫角色進行開啟。 |
polar_px_max_workers_number | 設置單個節點上的最大跨機并行查詢workers進程數,默認為30。該參數限制了單個節點上的最大并發度,節點上所有會話的跨機并行查詢workers進程數不能超過該參數大小。 |
polar_enable_px | 指定是否開啟跨機并行查詢功能。默認為off,即不開啟。 |
polar_px_dop_per_node | 設置當前會話并行查詢的并行度,默認為1,推薦值為當前CPU總核數。若設置該參數為N,則一個會話在每個節點上將會啟用N個px workers進程,用于處理當前的跨機并行查詢邏輯。 |
px_workers | 指定跨機并行查詢是否對特定表生效。默認不生效??鐧C并行查詢功能比較消耗計算節點集群資源,因此只有對設置了px_workers的表才使用該功能。例如:
|
synchronous_commit | WAL相關配置參數,指定當數據庫提交事務時是否需要等待WAL日志寫入硬盤后才向客戶端返回成功。取值如下:
說明 PX下參數需要設置為on。 |
示例
本示例以簡單的單表查詢操作,來描述跨機并行查詢的功能是否有效。
示例背景:
執行如下命令,創建test表并插入基礎數據。
CREATE TABLE test(id int);
INSERT INTO test SELECT generate_series(1,1000000);
EXPLAIN SELECT * FROM test;
默認情況下跨機并行查詢功能是不開啟的,單表查詢執行計劃為原生的Seq Scan,結果如下所示。
QUERY PLAN
--------------------------------------------------------
Seq Scan on test (cost=0.00..35.50 rows=2550 width=4)
(1 row)
通過以下步驟,開啟并使用跨機并行查詢功能:
- 對test表啟用跨機并行查詢功能。
ALTER TABLE test SET (px_workers=1); SET polar_enable_px=on; EXPLAIN SELECT * FROM test;
查詢結果如下:
QUERY PLAN ------------------------------------------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on test (scan partial) (cost=0.00..431.00 rows=1 width=4) Optimizer: PolarDB PX Optimizer (3 rows)
- 查詢當前所有只讀節點的名稱。
查詢命令如下:
SHOW polar_cluster_map;
查詢結果如下:
polar_cluster_map ------------------- node1,node2,node3 (1 row)
可得出當前集群有3個只讀節點,名稱分別為:node1,node2和node3。
- 指定node1和node2只讀節點參與跨機并行查詢。
命令如下:
SET polar_px_nodes='node1,node2';
查詢參與并行查詢的節點:
SHOW polar_px_nodes ;
查詢結果如下:
polar_px_nodes ---------------- node1,node2 (1 row)
性能數據
在5個只讀節點的情況下,測試的性能數據如下:
- 在
SELECT COUNT(*)
掃表的場景下,跨機并行查詢比單機并行查詢加速60倍。 - 在TPC-H場景下,跨機并行查詢比單機并行查詢加速30倍。說明 此處的TPC-H場景是基于TPC-H的基準測試,并不能與已發布的TPC-H基準測試結果相比較,此處提及的測試結果并不符合TPC-H基準測試的所有要求。
細粒度使用跨機并行查詢
各個粒度下如何使用跨機并行查詢進行分析型查詢如下所示:
- 系統粒度控制
系統粒度控制主要通過設置全局guc參數控制開啟跨機并行查詢,指定并行度。
示例postgres=# alter system set polar_enable_px=1; ALTER SYSTEM postgres=# alter system set polar_px_dop_per_node=1; ALTER SYSTEM postgres=# select pg_reload_conf(); pg_reload_conf ---------------- t (1 row) postgres=# \c postgres You are now connected to database "postgres" as user "postgres". postgres=# drop table if exists t1; DROP TABLE postgres=# select id into t1 from generate_series(1, 1000) as id order by id desc; SELECT 1000 postgres=# alter table t1 set (px_workers=1); ALTER TABLE postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows)
- 會話粒度控制會話粒度控制可以通過ALTER SESSION語法,也可以通過session級別的GUC參數控制。
- ALTER SESSION語法
ALTER SESSION ENABLE PARALLEL QUERY ALTER SESSION DISABLE PARALLEL QUERY ALTER SESSION FORCE PARALLEL QUERY [PARALLEL integer]
說明ALTER SESSION ENABLE PARALLEL QUERY
表示當前session允許通過hint或者并行語法來開啟并行查詢。ALTER SESSION DISABLE PARALLEL QUERY
表示當前session只能串行執行查詢,不能并行查詢,指定hint或者并行語法也無效。ALTER SESSION FORCE PARALLEL QUERY [PARALLEL integer]
表示強制當前session開啟并行執行,并行度為PARALLEL integer,如果后者沒有指定,則使用數據庫默認并行度polar_px_dop_per_node參數值。實際并行度優先級為:hint指定 > FORCE PARALLEL指定 > polar_px_dop_per_node指定。
ALTER SESSION命令會更改跨機并行查詢的配置參數,僅影響當前會話,會話重連后會重置,默認值enable。
示例--enable postgres=# set polar_enable_px = false; SET postgres=# set polar_px_enable_hint = true; SET postgres=# alter session enable parallel query; ALTER SESSION postgres=# explain (verbose, costs off) select /*+ PARALLEL(4)*/ * from t1 where id < 10; INFO: [HINTS] PX PARALLEL(4) accepted. QUERY PLAN ------------------------------------------- PX Coordinator 8:1 (slice1; segments: 8) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows)
--disable postgres=# set polar_enable_px = false; SET postgres=# set polar_px_enable_hint = true; SET postgres=# alter session disable parallel query; ALTER SESSION postgres=# explain (verbose, costs off) select /*+ PARALLEL(4)*/ * from t1 where id < 10; QUERY PLAN ------------------------ Seq Scan on public.t1 Output: id Filter: (t1.id < 10) (3 rows)
--force postgres=# set polar_enable_px = false; SET postgres=# set polar_px_enable_hint = false; SET postgres=# alter session force parallel query; ALTER SESSION postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows) postgres=# alter session force parallel query parallel 2; ALTER SESSION postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 4:1 (slice1; segments: 4) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows)
- GUC參數控制
GUC參數本身具有系統粒度屬性和會話粒度屬性,因此也可以實現會話粒度控制。
示例postgres=# set polar_enable_px = true; SET postgres=# set polar_px_dop_per_node = 1; SET postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows)
- ALTER SESSION語法
- 查詢粒度控制查詢粒度控制主要是通過sql hint指定當前sql查詢是否開啟跨機并行,以及并行度設置。具體Hint語法如下所示:
/*+ PARALLEL(DEFAULT) */ /*+ PARALLEL(integer) */ /*+ NO_PARALLEL(tablename) */
說明PARALLEL(DEFAULT)
表示指定使用跨機并行查詢,采用系統默認polar_px_dop_per_node并行度配置。PARALLEL(integer)
表示指定使用跨機并行查詢,采用指定的integer并行度配置。NO_PARALLEL(tablename)
表示指定表不能使用跨機并行查詢,整個查詢中如果包含這張表,則整個查詢也不能使用并行查詢。- 與Oracle兼容,當parallel hint混用時,存在以下注意事項:
- 多個hint塊時,/*+.A.*/ /*+.B.*/ /*+.C.*/,只有第一個hint塊生效。
- 單個hint塊中多個parallel hint并用時,/*+ parallel(A) parallel(B)*/,如果AB的dop值不相等,則AB的hint作用沖突,所有parallel hint失效;如果AB值相等,則其中一個生效。
- 單個hint塊中parallel/no_parallel hint并用時,/*+ parallel(A) no_parallel(t1)*/,則no_parallel的hint失效。
- 當前并行查詢只支持parallel/no_parallel hint,暫不支持其他hint。
- 查詢粒度的跨機并行查詢是否開啟,由GUC參數polar_px_enable_hint控制,默認為false。
示例postgres=# set polar_enable_px = false; SET postgres=# set polar_px_dop_per_node = 1; SET postgres=# set polar_px_enable_hint = true; SET postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------ Seq Scan on public.t1 Output: id Filter: (t1.id < 10) (3 rows) postgres=# explain (verbose, costs off) select /*+ PARALLEL(DEFAULT) */ * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows) postgres=# explain (verbose, costs off) select /*+ PARALLEL(4) */ * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 8:1 (slice1; segments: 8) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows) postgres=# explain (verbose, costs off) select /*+ PARALLEL(0) */ * from t1 where id < 10; QUERY PLAN ------------------------ Seq Scan on public.t1 Output: id Filter: (t1.id < 10) (3 rows) postgres=# explain (verbose, costs off) select /*+ NO_PARALLEL(t1) */ * from t1 where id < 10; QUERY PLAN ------------------------ Seq Scan on public.t1 Output: id Filter: (t1.id < 10) (3 rows)
- 各粒度組合效果三種粒度相互組合時,實際結果按照以下規則:
系統粒度 會話粒度 查詢粒度 實際結果 polar_enable_px=on polar_px_dop_per_node=X enable 不指定hint 并行,并行度X polar_enable_px=on polar_px_dop_per_node=X enable PARALLEL(Y) 并行,并行度Y polar_enable_px=on polar_px_dop_per_node=X enable NO_PARALLEL 不并行 polar_enable_px=on polar_px_dop_per_node=X disable 不指定hint 不并行 polar_enable_px=on polar_px_dop_per_node=X disable PARALLEL(Y) 不并行 polar_enable_px=on polar_px_dop_per_node=X disable NO_PARALLEL 不并行 polar_enable_px=on polar_px_dop_per_node=X FORCE PARALLEL Z 不指定hint 并行,并行度Z polar_enable_px=on polar_px_dop_per_node=X FORCE PARALLEL Z PARALLEL(Y) 并行,并行度Y polar_enable_px=on polar_px_dop_per_node=X FORCE PARALLEL Z NO_PARALLEL 不并行 polar_enable_px=off polar_px_dop_per_node=X enable 不指定hint 不并行 polar_enable_px=off polar_px_dop_per_node=X enable PARALLEL(Y) 并行, 并行度Y polar_enable_px=off polar_px_dop_per_node=X enable NO_PARALLEL 不并行 polar_enable_px=off polar_px_dop_per_node=X disable 不指定hint 不并行 polar_enable_px=off polar_px_dop_per_node=X disable PARALLEL(Y) 不并行 polar_enable_px=off polar_px_dop_per_node=X disable NO_PARALLEL 不并行 polar_enable_px=off polar_px_dop_per_node=X FORCE PARALLEL Z 不指定hint 并行,并行度Z polar_enable_px=off polar_px_dop_per_node=X FORCE PARALLEL Z PARALLEL(Y) 并行,并行度Y polar_enable_px=off polar_px_dop_per_node=X FORCE PARALLEL Z NO_PARALLEL 不并行