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)