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)