关于统一多级分区表

关于统一多级分区表

如果一个多级分区(MLP)表是一个统一分区表,GPORCA支持在该MLP上的查询。多级分区表是用SUBPARTITION子句创建的分区表。统一分区表必须满足下面这些条件。
  • 分区表结构统一。同一层上的每一个分区节点必须具有相同的层次结构。
  • 分区键约束必须一致且统一。在每一个子分区层次上,为每个分支创建的子表上的约束集必须匹配。
可以用几种方式显示分区表的信息,包括显示来自这些来源的信息:
  • pg_partitions系统视图包含分区表结构的信息。
  • pg_constraint系统目录表包含表约束的信息。
  • psql元命令\d+ tablename显示一个分区表的叶子子表的表约束。

例子

这个CREATE TABLE命令创建一个统一分区表。

CREATE TABLE mlp (id  int,  year int,  month int,  day int,
   region  text)
   DISTRIBUTED  BY (id)
    PARTITION BY RANGE ( year)
      SUBPARTITION  BY LIST (region)
        SUBPARTITION TEMPLATE (
          SUBPARTITION usa  VALUES ( 'usa'),
          SUBPARTITION europe  VALUES ( 'europe'),
          SUBPARTITION asia  VALUES ( 'asia'))
   (  START ( 2006)  END ( 2016) EVERY ( 5));
下面这些是为表mlp创建的子表和分区层次。这个层次由一个包含两个分支的子分区构成。
mlp_1_prt_11
   mlp_1_prt_11_2_prt_usa
   mlp_1_prt_11_2_prt_europe
   mlp_1_prt_11_2_prt_asia

mlp_1_prt_21
   mlp_1_prt_21_2_prt_usa
   mlp_1_prt_21_2_prt_europe
   mlp_1_prt_21_2_prt_asia

该表的层次是统一的,每个分区包含三个子表(子分区)的集合。区域子分区的约束也是统一的,分支表mlp_1_prt_11的子表上的约束集和分支表mlp_1_prt_21的子表的约束相同。

作为一种快速检查,这个查询显示这些分区的约束。
WITH tbl AS (SELECT oid, partitionlevel AS level, 
             partitiontablename AS part 
         FROM pg_partitions, pg_class 
         WHERE tablename = 'mlp' AND partitiontablename=relname 
            AND partitionlevel=1 ) 
  SELECT tbl.part, consrc 
    FROM tbl, pg_constraint 
    WHERE tbl.oid = conrelid ORDER BY consrc;
注意: 对于更复杂的分区表将需要修改该查询。例如,该查询不会对不同方案中的表名加以区分。

consrc列显示子分区上的约束。mlp_1_prt_1中子分区的区域约束集合匹配mlp_1_prt_2中子分区的约束。year的约束继承自父分支表。

           part           |               consrc
--------------------------+------------------------------------
 mlp_1_prt_2_2_prt_asia   | (region = 'asia'::text)
 mlp_1_prt_1_2_prt_asia   | (region = 'asia'::text)
 mlp_1_prt_2_2_prt_europe | (region = 'europe'::text)
 mlp_1_prt_1_2_prt_europe | (region = 'europe'::text)
 mlp_1_prt_1_2_prt_usa    | (region = 'usa'::text)
 mlp_1_prt_2_2_prt_usa    | (region = 'usa'::text)
 mlp_1_prt_1_2_prt_asia   | ((year >= 2006) AND (year < 2011))
 mlp_1_prt_1_2_prt_usa    | ((year >= 2006) AND (year < 2011))
 mlp_1_prt_1_2_prt_europe | ((year >= 2006) AND (year < 2011))
 mlp_1_prt_2_2_prt_usa    | ((year >= 2011) AND (year < 2016))
 mlp_1_prt_2_2_prt_asia   | ((year >= 2011) AND (year < 2016))
 mlp_1_prt_2_2_prt_europe | ((year >= 2011) AND (year < 2016))
(12 rows)
如果用下面的命令对例子中的分区表增加一个默认分区:
ALTER TABLE mlp ADD DEFAULT PARTITION def

该分区表仍然会是一个统一分区表。为默认分区创建的分支包含三个子表并且子表上的约束集匹配现有的子表约束集。

在上面的例子中,如果删除子分区mlp_1_prt_21_2_prt_asia并且为区域canada增加另一个子分区,则约束就不再统一。
ALTER TABLE mlp ALTER PARTITION FOR (RANK(2))
  DROP PARTITION asia ;

ALTER TABLE mlp ALTER PARTITION FOR (RANK(2))
  ADD PARTITION canada VALUES ('canada');

还有,如果在mlp_1_prt_21之下增加一个分区canada,分区结构会变得不再统一。

不过,如果对原始分区表的mlp_1_prt_21mlp_1_prt_11都增加子分区canada,它就还是一个统一分区表。

注意: 只有在一个分区级别上的分区集合的约束必须相同。这些分区的名称可以不同。