更新时间:2025-02-12 GMT+08:00
分享

SMP场景下的Partial Partition-wise Join

Partial Partition-wise Join是指相互Join的两张表中有一张表是分区表,另一张表可以为任意类型,在任意类型的这张表的上层需要增加一个Stream Redistribute算子,将数据分发后与分区表一侧进行匹配。

Partial Partition-wise Join路径生成的条件是分区表的分区键是一个Join key。

示例

--创建一个Hash分区表。
gaussdb=# CREATE TABLE hash_part
(
    a INTEGER,
    b INTEGER,
    c INTEGER
) PARTITION BY HASH(a) (
    PARTITION p1,
    PARTITION p2,
    PARTITION p3,
    PARTITION p4,
    PARTITION p5
);
CREATE TABLE

-- 创建一个非分区表。
gaussdb=# CREATE TABLE normal_table (
    a INTEGER,
    b INTEGER,
    c INTEGER
);
CREATE TABLE

--设置query_dop为5,开启SMP。
gaussdb=# SET query_dop = 5;
SET
gaussdb=# SET enable_force_smp = on;
SET

--关闭SMP场景下的Partition-wise Join开关。
gaussdb=# SET enable_smp_partitionwise = off;
SET

--查看非Partition-wise Join的计划。从计划中可以看出来,在通过Partition Iterator+Partitioned Seq Scan两层算子完成数据扫描之后,通过Streaming(type: LOCAL REDISTRIBUTE)算子对数据进行了一次重分布,用于保证Join算子中数据能够相互匹配。
gaussdb=# EXPLAIN (costs off) SELECT * FROM normal_table t1, hash_part t2 WHERE t1.a=t2.a;
                             QUERY PLAN                             
--------------------------------------------------------------------
 Streaming(type: LOCAL GATHER dop: 1/5)
   ->  Hash Join
         Hash Cond: (t1.a = t2.a)
         ->  Streaming(type: LOCAL REDISTRIBUTE dop: 5/5)
               ->  Seq Scan on normal_table t1
         ->  Hash
               ->  Streaming(type: LOCAL REDISTRIBUTE dop: 5/5)
                     ->  Partition Iterator
                           Iterations: 5
                           ->  Partitioned Seq Scan on hash_part t2
                                 Selected Partitions:  1..5
(11 rows)

--打开SMP场景下的Partition-wise Join开关。
gaussdb=# SET enable_smp_partitionwise = on;
SET

--查看Partition-wise Join的执行计划。从计划中可以看出,Partial Partition-wise Join计划消除掉了分布表hash_part一侧的Streaming算子,即分区表的数据不再需要在线程之间重新分布,减少了数据搬运的开销,提升了Join操作的性能。
gaussdb=# EXPLAIN (costs off) SELECT * FROM normal_table t1, hash_part t2 WHERE t1.a=t2.a;
                          QUERY PLAN                          
--------------------------------------------------------------
 Streaming(type: LOCAL GATHER dop: 1/5)
   ->  Hash Join (Partition-wise Join)
         Hash Cond: (t1.a = t2.a)
         ->  Streaming(type: LOCAL REDISTRIBUTE dop: 5/5)
               ->  Seq Scan on normal_table t1
         ->  Hash
               ->  Partition Iterator
                     Iterations: 5
                     ->  Partitioned Seq Scan on hash_part t2
                           Selected Partitions:  1..5
(10 rows)

-- 删除分区表
gaussdb=# DROP TABLE hash_part;
DROP TABLE
gaussdb=# DROP TABLE normal_table;
DROP TABLE

相关文档