本文介绍了PolarDB PostgreSQL版的并行INSERT功能。
前提条件
支持的PolarDB PostgreSQL版的版本如下:
PostgreSQL 11(内核小版本1.1.17及以上)
PostgreSQL 14(内核小版本14.8.12.0及以上)
您可通过如下语句查看PolarDB PostgreSQL版的内核小版本的版本号:
PostgreSQL 11
show polar_version;PostgreSQL 14
select version();
简介
PolarDB PostgreSQL版支持弹性跨机并行查询(ePQ)特性,通过利用集群中多个计算节点来提升查询性能。同时,ePQ也支持在读写节点上通过多进程并行写入,实现对INSERT语句的加速。
ePQ的并行INSERT功能用于加速INSERT INTO ... SELECT ...这种读写兼备的SQL。对于SQL中的SELECT部分,ePQ将启动多个进程并行执行查询;对于SQL中的INSERT部分,ePQ将在读写节点上启动多个进程并行执行写入。执行写入的进程与执行查询的进程之间通过Motion算子进行数据传递。
支持并行INSERT的表类型如下:
普通表
分区表
(部分)外部表
并行INSERT支持动态调整写入并行度(写入进程数量),在查询不成为瓶颈的条件下性能最高能提升三倍。
原理介绍
并行查询和并行写入以流水线的形式同时进行。执行过程如下图所示:
ePQ 对并行INSERT的执行过程如下:
ePQ优化器以查询解析得到的语法树作为输入,产生计划树。
ePQ执行器将计划树分发到各计算节点,并创建并行查询/并行写入进程,开始执行各自负责执行的子计划。
并行查询进程从存储中并行读取各自负责的数据分片,并将数据发送到Motion算子。
并行写入进程从Motion算子中获取数据,向存储并行写入数据。
参数说明
通过
polar_px_dop_per_node参数调整INSERT INTO ... SELECT ...中查询的并行度。通过
polar_px_insert_dop_num参数调整INSERT INTO ... SELECT ...中写入的并行度。
当查询并行度较低时,逐步提升写入并行度,SQL执行时间将会逐渐下降并趋于平缓,趋于平缓的原因是查询速度跟不上写入速度而成为瓶颈。
当查询并行度较高时,逐步提升写入并行度,SQL执行时间将会逐渐下降并趋于平缓;趋于平缓的原因是并行写入只能在读写节点上进行,写入速度因多个写入进程对表页面扩展锁的争抢而跟不上查询速度,成为瓶颈。
示例
创建两张表
t1和t2,并向t1中插入数据。CREATE TABLE t1 (id INT); CREATE TABLE t2 (id INT); INSERT INTO t1 SELECT generate_series(1,100000);开启ePQ及并行
INSERT功能。SET polar_enable_px TO ON; SET polar_px_enable_insert_select TO ON;通过
INSERT语句将t1表中的所有数据插入到t2表中。查看并行INSERT的执行计划。EXPLAIN INSERT INTO t2 SELECT * FROM t1; QUERY PLAN ----------------------------------------------------------------------------------------- Insert on t2 (cost=0.00..952.87 rows=33334 width=4) -> Result (cost=0.00..0.00 rows=0 width=0) -> PX Hash 6:3 (slice1; segments: 6) (cost=0.00..432.04 rows=100000 width=8) -> Partial Seq Scan on t1 (cost=0.00..431.37 rows=16667 width=4) Optimizer: PolarDB PX Optimizer (5 rows)其中的
PX Hash 6:3表示6个并行查询t1的进程通过Motion算子将数据传递给3个并行写入t2的进程。通过参数
polar_px_insert_dop_num动态调整写入并行度,查看并行INSERT的执行计划。SET polar_px_insert_dop_num TO 12; EXPLAIN INSERT INTO t2 SELECT * FROM t1; QUERY PLAN ------------------------------------------------------------------------------------------ Insert on t2 (cost=0.00..952.87 rows=8334 width=4) -> Result (cost=0.00..0.00 rows=0 width=0) -> PX Hash 6:12 (slice1; segments: 6) (cost=0.00..432.04 rows=100000 width=8) -> Partial Seq Scan on t1 (cost=0.00..431.37 rows=16667 width=4) Optimizer: PolarDB PX Optimizer (5 rows)通过执行计划中的
PX Hash 6:12显示,并行查询t1的进程数量不变,并行写入t2的进程数量变为12。