PolarDB PostgreSQL版支持根據表的大小或執行計劃的代價來控制對查詢使用ePQ還是單機執行。
前提條件
支持的PolarDB PostgreSQL版的版本如下:
PostgreSQL 14(內核小版本14.9.15.0及以上)。
您可通過如下語句查看PolarDB PostgreSQL版的內核小版本的版本號:
select version();
背景信息
ePQ善于解決復雜、執行時間長的OLAP長查詢,不適用于簡單、執行時間短的OLTP短查詢。對于短查詢而言,計算節點之間建立連接、數據交換、銷毀連接的開銷反而會導致性能下降。PolarDB PostgreSQL版支持根據表的大小或執行計劃的代價來控制對查詢使用ePQ還是單機執行,從而在查詢不同大小的表和執行不同代價的計劃時,能夠選擇性能更好的查詢執行方式。
注意事項
執行計劃代價閾值和表大小閾值目前僅支持以下對象或操作:
普通表
分區表
物化視圖
不帶有ePQ的 hint
/*+ PX() */
的查詢
參數說明
參數 | 說明 |
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進行查詢,取值如下:
|
使用指南
準備數據。
CREATE TABLE test (id INT); INSERT INTO test SELECT generate_series(1, 1000); ANALYZE test;
查看執行計劃代價。
顯式關閉ePQ,查看單機執行計劃。
SET polar_enable_px TO OFF; EXPLAIN SELECT COUNT(*) FROM test; QUERY PLAN -------------------------------------------------------------- Aggregate (cost=17.50..17.51 rows=1 width=8) -> Seq Scan on test (cost=0.00..15.00 rows=1000 width=0) (2 rows)
在上述執行計劃中,每一行內的
cost=xxx..xxx
表示當前算子的估算執行代價,..
前面的為啟動代價,后面的為總代價。最頂層算子的總代價可以被認為是這條查詢的總執行代價。例如,上述執行計劃中的17.51
即為總執行代價。由于單機執行計劃的總代價低于參數polar_px_min_pg_plan_cost
所指定的最小執行計劃代價,所以即使開啟ePQ,這條查詢也不會使用ePQ。SET polar_enable_px TO ON; EXPLAIN SELECT COUNT(*) FROM test; QUERY PLAN -------------------------------------------------------------- Aggregate (cost=17.50..17.51 rows=1 width=8) -> Seq Scan on test (cost=0.00..15.00 rows=1000 width=0) (2 rows)
查看表大小。
通過函數
pg_relation_size
查看表的大小。SELECT pg_size_pretty(pg_relation_size('test')); pg_size_pretty ---------------- 40 kB (1 row)
上述結果顯示
test
表的大小為40 kB,低于polar_px_min_table_scan_size
所指定的最小表大小,所以即使開啟ePQ,任何只引用test
表的查詢都不會使用ePQ。SET polar_enable_px TO ON; EXPLAIN SELECT COUNT(*) FROM test AS a, test AS b, test AS c WHERE a.id > b.id AND b.id > c.id; QUERY PLAN ---------------------------------------------------------------------------------- Aggregate (cost=5292822.50..5292822.51 rows=1 width=8) -> Nested Loop (cost=0.00..5015045.00 rows=111111000 width=0) Join Filter: (b.id > c.id) -> Nested Loop (cost=0.00..15032.50 rows=333333 width=4) Join Filter: (a.id > b.id) -> Seq Scan on test a (cost=0.00..15.00 rows=1000 width=4) -> Materialize (cost=0.00..20.00 rows=1000 width=4) -> Seq Scan on test b (cost=0.00..15.00 rows=1000 width=4) -> Materialize (cost=0.00..20.00 rows=1000 width=4) -> Seq Scan on test c (cost=0.00..15.00 rows=1000 width=4) (10 rows)
取消閾值。
如果想要忽略執行計劃代價閾值和表大小閾值,強行讓查詢使用ePQ,可以通過設置參數
polar_px_force_use
實現。SET polar_enable_px TO ON; SET polar_px_force_use TO ON; EXPLAIN SELECT COUNT(*) FROM test; QUERY PLAN ------------------------------------------------------------------------------------- Finalize Aggregate (cost=0.00..431.00 rows=1 width=8) -> PX Coordinator 6:1 (slice1; segments: 6) (cost=0.00..431.00 rows=1 width=8) -> Partial Aggregate (cost=0.00..431.00 rows=1 width=8) -> Partial Seq Scan on test (cost=0.00..431.00 rows=167 width=1) Optimizer: PolarDB PX Optimizer (5 rows)
插入數據后重新執行計劃代價。
向表中再插入一定量的數據,使其滿足啟用ePQ的條件。
INSERT INTO test SELECT generate_series(1, 10000000); ANALYZE test;
此時,
test
表的大小已經超過了polar_px_min_table_scan_size
所指定的最小表大小。SELECT pg_size_pretty(pg_relation_size('test')); pg_size_pretty ---------------- 348 MB (1 row)
如下查詢的單機執行計劃代價也超過了
polar_px_min_pg_plan_cost
所指定的最小執行計劃代價。SET polar_enable_px TO OFF; EXPLAIN SELECT COUNT(*) FROM test; QUERY PLAN ----------------------------------------------------------------------------------------- Finalize Aggregate (cost=97621.42..97621.43 rows=1 width=8) -> Gather (cost=97621.21..97621.42 rows=2 width=8) Workers Planned: 2 -> Partial Aggregate (cost=96621.21..96621.22 rows=1 width=8) -> Parallel Seq Scan on test (cost=0.00..86205.77 rows=4166177 width=0) (5 rows)
開啟ePQ,上述查詢將會通過ePQ執行。
SET polar_enable_px TO ON; SET polar_px_force_use TO OFF; EXPLAIN SELECT COUNT(*) FROM test; QUERY PLAN -------------------------------------------------------------------------------------- Finalize Aggregate (cost=0.00..470.76 rows=1 width=8) -> PX Coordinator 6:1 (slice1; segments: 6) (cost=0.00..470.76 rows=1 width=8) -> Partial Aggregate (cost=0.00..470.76 rows=1 width=8) -> Partial Seq Scan on test (cost=0.00..467.66 rows=1666471 width=1) Optimizer: PolarDB PX Optimizer (5 rows)