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