并行INSERT

本文介绍了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的执行过程如下:

  1. ePQ优化器以查询解析得到的语法树作为输入,产生计划树。

  2. ePQ执行器将计划树分发到各计算节点,并创建并行查询/并行写入进程,开始执行各自负责执行的子计划。

  3. 并行查询进程从存储中并行读取各自负责的数据分片,并将数据发送到Motion算子。

  4. 并行写入进程从Motion算子中获取数据,向存储并行写入数据。

参数说明

  • 通过polar_px_dop_per_node参数调整INSERT INTO ... SELECT ...中查询的并行度。

  • 通过polar_px_insert_dop_num参数调整INSERT INTO ... SELECT ...中写入的并行度。

当查询并行度较低时,逐步提升写入并行度,SQL执行时间将会逐渐下降并趋于平缓,趋于平缓的原因是查询速度跟不上写入速度而成为瓶颈。

当查询并行度较高时,逐步提升写入并行度,SQL执行时间将会逐渐下降并趋于平缓;趋于平缓的原因是并行写入只能在读写节点上进行,写入速度因多个写入进程对表页面扩展锁的争抢而跟不上查询速度,成为瓶颈。

示例

  1. 创建两张表t1t2,并向t1中插入数据。

    CREATE TABLE t1 (id INT);
    CREATE TABLE t2 (id INT);
    INSERT INTO t1 SELECT generate_series(1,100000);
  2. 开启ePQ及并行INSERT功能。

    SET polar_enable_px TO ON;
    SET polar_px_enable_insert_select TO ON;
  3. 通过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的进程。

  4. 通过参数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