这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

定义分区

可以为新表和现有表指定分区:

1 - 对新表进行分区

使用 CREATE TABLE 对新表进行分区,由 PARTITION BY 子句指定:

CREATE TABLE table-name... PARTITION BY partition‑expression [ GROUP BY group‑expression ] [ REORGANIZE ];

以下语句创建 store_orders 表并将数据加载到其中。CREATE TABLE 语句包含一个简单的分区子句,指定按年份对数据进行分区:

=> CREATE TABLE public.store_orders
(
    order_no int,
    order_date timestamp NOT NULL,
    shipper varchar(20),
    ship_date date
)
UNSEGMENTED ALL NODES
PARTITION BY YEAR(order_date);
CREATE TABLE
=> COPY store_orders FROM '/home/dbadmin/export_store_orders_data.txt';
41834

当 COPY 将新表数据加载到 ROS 存储中时,Tuple Mover 会将每年的订单划分为单独的分区,且将这些分区合并到 ROS 容器中,以执行表的分区子句。

在这种情况下,Tuple Mover 为加载的数据创建四个分区键(2017、2016、2015 和 2014),并将数据相应划分到单独的 ROS 容器中:

=> SELECT dump_table_partition_keys('store_orders');
... Partition keys on node v_vmart_node0001
  Projection 'store_orders_super'
   Storage [ROS container]
     No of partition keys: 1
     Partition keys: 2017
   Storage [ROS container]
     No of partition keys: 1
     Partition keys: 2016
   Storage [ROS container]
     No of partition keys: 1
     Partition keys: 2015
   Storage [ROS container]
     No of partition keys: 1
     Partition keys: 2014

 Partition keys on node v_vmart_node0002
  Projection 'store_orders_super'
   Storage [ROS container]
     No of partition keys: 1
     Partition keys: 2017
...

(1 row)

当新数据加载到 store_orders 中时,Tuple Mover 会将其合并到适当的分区中,以此根据需要创建新的分区键。

2 - 对现有表数据进行分区

使用 ALTER TABLE 对现有表进行分区或重新分区,由 PARTITION BY 子句指定:

ALTER TABLE table-name PARTITION BY partition‑expression [ GROUP BY group‑expression ] [ REORGANIZE ];

例如,可以对前面定义store_orders 表进行重新分区。下面的 ALTER TABLE 将每年的所有 store_orders 数据划分为每月分区,每个分区键标识订单日期的年份和月份:

=> ALTER TABLE store_orders
     PARTITION BY EXTRACT(YEAR FROM order_date)*100 + EXTRACT(MONTH FROM order_date)
         GROUP BY EXTRACT(YEAR from order_date)*100 + EXTRACT(MONTH FROM order_date);
NOTICE 8364:  The new partitioning scheme will produce partitions in 42 physical storage containers per projection
WARNING 6100:  Using PARTITION expression that returns a Numeric value
HINT:  This PARTITION expression may cause too many data partitions.  Use of an expression that returns a more accurate value, such as a regular VARCHAR or INT, is encouraged
WARNING 4493:  Queries using table "store_orders" may not perform optimally since the data may not be repartitioned in accordance with the new partition expression
HINT:  Use "ALTER TABLE public.store_orders REORGANIZE;" to repartition the data

执行此语句后,Vertica 会删除现有的分区键。但是,partition 子句会省略 REORGANIZE,以便现有数据仍然根据前一个 partition 子句进行存储。这可能会使表分区处于不一致状态,并对查询性能、DROP_PARTITIONS 和节点恢复产生负面影响。在这种情况下,必须通过以下方式之一显式请求 Vertica 将现有数据重新组织到新分区中:

  • 发出 ALTER TABLE...REORGANIZE:

    ALTER TABLE table-name REORGANIZE;
    
  • 调用 Vertica 元函数 PARTITION_TABLE

例如:

=> ALTER TABLE store_orders REORGANIZE;
NOTICE 4785:  Started background repartition table task
ALTER TABLE

ALTER TABLE...REORGANIZE 和 PARTITION_TABLE 的运行方式相同:两者都会拆分分区键与新 partition 子句不相符的任何 ROS 容器。在执行下一次合并时,Tuple Mover 会将分区合并到相应的 ROS 容器中。

3 - 分区分组

分区组将分区合并为逻辑子集,从而最大限度减少 ROS 存储的使用。减少存储分区数据的 ROS 容器数有助于促进 DELETEUPDATE 等 DML 操作,并避免 ROS 推回。例如,可以按年份对日期分区进行分组。通过这样做,Tuple Mover 会为每个年份组分配 ROS 容器,并相应地将各个分区合并到这些 ROS 容器中。

创建分区组

可以通过使用 GROUP BY 子句限定 PARTITION BY 子句来创建分区组:

ALTER TABLE table-name PARTITION BY partition‑expression [ GROUP BY group‑expression ]

GROUP BY 子句指定如何将分区键合并到组中,其中每个组由唯一的分区组键标识。例如,以下 ALTER TABLE 语句指定按订单日期对 store_orders 表进行重新分区(如对新表进行分区中所示),按年份对分区键进行分组。组表达式 DATE_TRUNC('year', (order_date)::DATE) 使用分区表达式 order_date::DATE 生成分区组键:

=> ALTER TABLE store_orders
     PARTITION BY order_date::DATE GROUP BY DATE_TRUNC('year', (order_date)::DATE) REORGANIZE;
NOTICE 8364:  The new partitioning scheme will produce partitions in 4 physical storage containers per projection
NOTICE 4785:  Started background repartition table task

在这种情况下,order_date 列的日期跨越四年。Tuple Mover 会创建四个分区组键,并相应地将 store_orders 分区合并到组特定的 ROS 存储容器中:


=> SELECT DUMP_TABLE_PARTITION_KEYS('store_orders');
 ...
 Partition keys on node v_vmart_node0001
  Projection 'store_orders_super'
   Storage [ROS container]
     No of partition keys: 173
     Partition keys: 2017-01-02 2017-01-03 2017-01-04 ... 2017-09-25 2017-09-26 2017-09-27
   Storage [ROS container]
     No of partition keys: 212
     Partition keys: 2016-01-01 2016-01-04 2016-01-05 ... 2016-11-23 2016-11-24 2016-11-25
   Storage [ROS container]
     No of partition keys: 213
     Partition keys: 2015-01-01 2015-01-02 2015-01-05 ... 2015-11-23 2015-11-24 2015-11-25
2015-11-26 2015-11-27
   Storage [ROS container]
     No of partition keys: 211
     Partition keys: 2014-01-01 2014-01-02 2014-01-03 ... 2014-11-25 2014-11-26 2014-11-27
  Projection 'store_orders_super'
   Storage [ROS container]
     No of partition keys: 173
...

管理组内的分区

可以使用各种分区管理函数(例如 DROP_PARTITIONSMOVE_PARTITIONS_TO_TABLE),来定位给定分区组内或跨多个分区组的订单日期范围。在前面的示例中,每个组都包含给定年份内不同日期的分区键。可以使用 DROP_PARTITIONS 删除跨越两年(2014 年和 2015 年)的订单日期:

=> SELECT DROP_PARTITIONS('store_orders', '2014-05-30', '2015-01-15', 'true');