MaxCompute支持对已有表的分区执行变更操作,如添加分区、删除分区、修改分区值等,您可以根据实际业务场景执行相应操作。
MaxCompute SQL的分区操作命令如下。
操作 | 功能 | 角色 | 操作入口 |
为已存在的分区表新增分区。 | 具备修改表权限(Alter)的用户 | 本文中的命令您可以在如下工具平台执行: | |
为已存在的分区表删除分区。 | |||
修改分区表中分区的 | |||
修改分区表的分区值。 | |||
对分区表的分区进行合并,即同一个分区表下的多个分区合并成一个分区,同时删除被合并的分区维度的信息,把数据移动到指定分区。 | |||
清空指定分区的数据。 |
使用限制
目前支持TINYINT、SMALLINT、INT、BIGINT、CHAR、VARCHAR和STRING数据类型的字段设为分区列。
单表分区层级最多6级。
单表分区数最多允许60000个分区。
一次最多查询分区数为10000个。
Transaction类型的分区表不支持merge partition操作。
Delta Table类型的非分区表不支持清空操作、不支持更改表的write.bucket.num属性。
添加分区
为已存在的分区表新增分区。
限制条件
MaxCompute单表支持的分区数量上限为6万个。
对于有多级分区的表,如果需要添加新的分区值,必须指明全部的分区。
仅支持新增分区值,不支持新增分区字段。
命令格式
ALTER TABLE <table_name> ADD [if NOT EXISTS] PARTITION <pt_spec> [PARTITION <pt_spec> PARTITION <pt_spec>...];
参数说明
参数
是否必填
说明
table_name
是
待新增分区的分区表名称。
if not exists
否
如果未指定if not exists而同名的分区已存在,会执行失败并返回报错。
pt_spec
是
新增的分区,格式为:
(partition_col1 = partition_col_value1, partition_col2 = partition_col_value2, ...)
。其中partition_col是分区字段,partition_col_value是分区值。分区字段不区分大小写,分区值区分大小写。使用示例
示例1:给表sale_detail添加一个分区,用来存储2013年12月杭州地区的销售记录。
ALTER TABLE sale_detail ADD if NOT EXISTS PARTITION (sale_date='201312', region='hangzhou');
示例2:给表sale_detail同时添加两个分区,用来存储2013年12月北京和上海地区的销售记录。
ALTER TABLE sale_detail ADD if NOT EXISTS PARTITION (sale_date='201312', region='beijing') partition (sale_date='201312', region='shanghai');
示例3:给表sale_detail添加分区,仅指定一个分区字段sale_date,返回报错,需要同时指定2个分区字段sale_date和region。
ALTER TABLE sale_detail ADD if NOT EXISTS PARTITION (sale_date='20111011');
示例4:增加Delta Table表分区
--创建delta table表 CREATE TABLE mf_tt (pk bigint NOT NULL PRIMARY key, val bigint NOT NULL) partitioned BY (dd string, hh string) tblproperties ("transactional"="true"); --添加分区 ALTER TABLE mf_tt ADD PARTITION (dd='01', hh='01');
示例5:修改Delta Table表属性
--更新bucket数据,目前只支持分区表,不支持非分区表 ALTER TABLE mf_tt3 SET tblproperties("write.bucket.num"="64"); --更新retain属性 ALTER TABLE mf_tt3 SET tblproperties("acid.data.retain.hours"="60");
删除分区
为已存在的分区表删除分区。
MaxCompute支持通过条件筛选方式删除分区。如果您希望一次性删除符合某个规则条件的多个分区,可以使用表达式指定筛选条件,通过筛选条件匹配分区并批量删除分区。
限制条件
每个分区过滤子句只能访问一个分区列。
表达式用到的函数必须是内建的Scalar函数。
注意事项
删除分区之后,MaxCompute项目的存储量会降低。
您可以结合MaxCompute提供的生命周期功能,实现自动回收旧分区的能力。更多生命周期信息,请参见生命周期。
命令格式
未指定筛选条件
--一次删除一个分区。 ALTER TABLE <table_name> DROP [if EXISTS] PARTITION <pt_spec>; --一次删除多个分区。 ALTER TABLE <table_name> DROP [if EXISTS] PARTITION <pt_spec>,PARTITION <pt_spec>[,PARTITION <pt_spec>....];
指定筛选条件
ALTER TABLE <table_name> DROP [if EXISTS] PARTITION <partition_filtercondition>;
参数说明
参数
是否必填
说明
table_name
是
待删除分区的分区表名称。
if exists
否
如果未指定if exists且分区不存在,则返回报错。
pt_spec
是
删除的分区。格式为:
(partition_col1 = partition_col_value1, partition_col2 = partition_col_value2, ...)
。其中partition_col是分区字段,partition_col_value是分区值。分区字段不区分大小写,分区值区分大小写。partition_filtercondition
否
指定筛选条件时必填。分区筛选条件,不区分大小写。格式如下:
partition_filtercondition : PARTITION (<partition_col> <relational_operators> <partition_col_value>) | PARTITION (scalar(<partition_col>) <relational_operators> <partition_col_value>) | PARTITION (<partition_filtercondition1> AND|OR <partition_filtercondition2>) | PARTITION (NOT <partition_filtercondition>) | PARTITION (<partition_filtercondition1>)[,PARTITION (<partition_filtercondition2>), ...]
介绍如下:
partition_col:分区名称。
relational_operators:关系运算符,详情请参见运算符。
partition_col_value:分区列比较值或正则表达式,与分区列数据类型保持一致。
scalar():Scalar函数。Scalar函数基于输入值生成对应的标量,对分区列的值(partition_col)进行处理后再按照指定的关系运算符relational_operators与partition_col_value做比较。
分区过滤条件支持逻辑运算符NOT、AND和OR。支持通过NOT过滤条件子句,取过滤规则的补集。支持多个过滤条件子句以AND或OR的关系组成整体分区匹配规则。
支持多个分区过滤子句,当多个分区过滤子句以英文逗号(,)分隔时,每个过滤子句的逻辑以OR的关系组成整体分区匹配规则。
使用示例
未指定筛选条件
--从表sale_detail中删除一个分区,2013年12月杭州分区的销售记录。 ALTER TABLE sale_detail DROP if EXISTS PARTITION(sale_date='201312',region='hangzhou'); --从表sale_detail中同时删除两个分区,2013年12月杭州和上海分区的销售记录。 ALTER TABLE sale_detail DROP if EXISTS PARTITION(sale_date='201312',region='hangzhou'),PARTITION(sale_date='201312',region='shanghai');
指定筛选条件
--创建分区表 CREATE TABLE if NOT EXISTS sale_detail( shop_name STRING, customer_id STRING, total_price DOUBLE) partitioned BY (sale_date STRING); --添加分区 ALTER TABLE sale_detail ADD if NOT EXISTS PARTITION (sale_date= '201910') PARTITION (sale_date= '201911') PARTITION (sale_date= '201912') PARTITION (sale_date= '202001') PARTITION (sale_date= '202002') PARTITION (sale_date= '202003') PARTITION (sale_date= '202004') PARTITION (sale_date= '202005') PARTITION (sale_date= '202006') PARTITION (sale_date= '202007'); --批量删除分区 ALTER TABLE sale_detail DROP if EXISTS PARTITION(sale_date < '201911'); ALTER TABLE sale_detail DROP if EXISTS PARTITION(sale_date >= '202007'); ALTER TABLE sale_detail DROP if EXISTS PARTITION(sale_date LIKE '20191%'); ALTER TABLE sale_detail DROP if EXISTS PARTITION(sale_date IN ('202002','202004','202006')); ALTER TABLE sale_detail DROP if EXISTS PARTITION(sale_date BETWEEN '202001' AND '202007'); ALTER TABLE sale_detail DROP if EXISTS PARTITION(substr(sale_date, 1, 4) = '2020'); ALTER TABLE sale_detail DROP if EXISTS PARTITION(sale_date < '201912' OR sale_date >= '202006'); ALTER TABLE sale_detail DROP if EXISTS PARTITION(sale_date > '201912' AND sale_date <= '202004'); ALTER TABLE sale_detail DROP if EXISTS PARTITION(NOT sale_date > '202004'); --支持多个分区过滤表达式,表达式之间是OR的关系 ALTER TABLE sale_detail DROP if EXISTS PARTITION(sale_date < '201911'), PARTITION(sale_date >= '202007'); --添加其他格式分区 ALTER TABLE sale_detail ADD IF NOT EXISTS PARTITION (sale_date= '2019-10-05') PARTITION (sale_date= '2019-10-06') PARTITION (sale_date= '2019-10-07'); --批量删除分区,使用正则表达式匹配分区。 ALTER TABLE sale_detail DROP if EXISTS PARTITION(sale_date RLIKE '2019-\\d+-\\d+'); --创建多级分区表。 CREATE TABLE if NOT EXISTS region_sale_detail( shop_name STRING, customer_id STRING, total_price DOUBLE) partitioned BY (sale_date STRING , region STRING ); --添加分区。 ALTER TABLE region_sale_detail ADD IF NOT EXISTS PARTITION (sale_date= '201910',region = 'shanghai') PARTITION (sale_date= '201911',region = 'shanghai') PARTITION (sale_date= '201912',region = 'shanghai') PARTITION (sale_date= '202001',region = 'shanghai') PARTITION (sale_date= '202002',region = 'shanghai') PARTITION (sale_date= '201910',region = 'beijing') PARTITION (sale_date= '201911',region = 'beijing') PARTITION (sale_date= '201912',region = 'beijing') PARTITION (sale_date= '202001',region = 'beijing') PARTITION (sale_date= '202002',region = 'beijing'); --执行如下语句批量删除多级分区,两个匹配条件是或的关系,会将sale_date小于201911或region等于beijing的分区都删除掉。 ALTER TABLE region_sale_detail DROP if EXISTS PARTITION(sale_date < '201911'),PARTITION(region = 'beijing'); --如果删除sale_date小于201911且region等于beijing的分区,可以使用如下方法。 ALTER TABLE region_sale_detail DROP if EXISTS PARTITION(sale_date < '201911', region = 'beijing');
批量删除多级分区时,在一个
partition
过滤子句中,不能根据多个分区列编写组合条件匹配分区,如下语句会报错FAILED: ODPS-0130071:[1,82] Semantic analysis exception - invalid column reference region, partition expression must have one and only one column reference
。--分区过滤子句只能访问一个分区列,如下语句报错。 ALTER TABLE region_sale_detail DROP if EXISTS PARTITION(sale_date < '201911' AND region = 'beijing');
修改分区的更新时间
MaxCompute SQL提供touch
操作,用于修改分区表中分区的LastModifiedTime
。此操作会将LastModifiedTime
修改为当前时间。此时,MaxCompute会认为数据有变动,重新计算生命周期。
使用限制
对于有多级分区的表,必须指明全部的分区。
命令格式
ALTER TABLE <table_name> touch PARTITION (<pt_spec>);
参数说明
参数
是否必填
说明
table_name
是
待修改分区更新时间的分区表名称。如果表不存在,则返回报错。
pt_spec
是
需要修改更新时间的分区信息。格式为:
(partition_col1 = partition_col_value1, partition_col2 = partition_col_value2, ...)
。其中partition_col是分区字段,partition_col_value是分区值。如果指定的分区字段或分区值不存在,则返回报错。使用示例
--修改表sale_detail的分区sale_date='201312', region='shanghai'的LastModifiedTime。 ALTER TABLE sale_detail touch PARTITION (sale_date='201312', region='shanghai');
修改分区值
MaxCompute SQL支持通过rename
操作更改分区表的分区值。
使用限制
不支持修改分区列的列名,只能修改分区列对应的值。
对于有多级分区的表,必须指明全部的分区。
命令格式
ALTER TABLE <table_name> PARTITION (<pt_spec>) rename TO PARTITION (<new_pt_spec>);
参数说明
参数
是否必填
说明
table_name
是
待修改分区值的表名称。
pt_spec
是
需要修改分区值的分区信息。格式为:
(partition_col1 = partition_col_value1, partition_col2 = partition_col_value2, ...)
。其中partition_col是分区字段,partition_col_value是分区值。如果指定的分区字段或分区值不存在,则返回报错。new_pt_spec
是
修改后的分区信息。格式为:
(partition_col1 = new_partition_col_value1, partition_col2 = new_partition_col_value2, ...)
。其中partition_col是分区字段,new_partition_col_value是新分区值。使用示例
--修改表sale_detail的分区值。 ALTER TABLE sale_detail PARTITION (sale_date = '201312', region = 'hangzhou') rename TO PARTITION (sale_date = '201310', region = 'beijing');
合并分区
MaxCompute SQL提供merge partition
对分区表的分区进行合并,即将同一个分区表下的多个分区合并成一个分区,同时删除被合并的分区维度的信息,把数据移动到指定分区。
使用限制
不支持外部表,聚簇表合并后的分区会消除聚簇属性。
一次性合并分区数量限制为4000个。
命令格式
ALTER TABLE <table_name> MERGE [if EXISTS] PARTITION (<predicate>) [, PARTITION(<predicate2>) ...] overwrite PARTITION (<fullpartitionSpec>) [purge];
参数说明
参数
是否必填
说明
table_name
是
待合并分区的分区表名称。
if exists
否
如果未指定if exists,且分区不存在,会执行失败并返回报错。如果指定if exists后不存在满足
merge
条件的分区,则不生成新分区。如果运行过程中出现源数据被并发修改(包括insert
、rename
或drop
)时,即使指定if exists也会报错。predicate
是
筛选待合并分区需要满足的条件。
fullpartitionSpec
是
目标分区信息。
purge
否
可选关键字。选择该字段,则会清理session目录,默认清理3天内的日志。详情请参见Purge。
使用示例
示例1:合并满足指定条件的分区到目标分区。
--查看分区表的分区。 SHOW partitions intpstringstringstring; ds=20181101/hh=00/mm=00 ds=20181101/hh=00/mm=10 ds=20181101/hh=10/mm=00 ds=20181101/hh=10/mm=10 --合并所有满足hh='00'的分区到hh='00',mm='00'中。 ALTER TABLE intpstringstringstring MERGE PARTITION(hh='00') overwrite PARTITION(ds='20181101', hh='00', mm='00'); --查看合并后的分区。 SHOW partitions intpstringstringstring; ds=20181101/hh=00/mm=00 ds=20181101/hh=10/mm=00 ds=20181101/hh=10/mm=10
示例2:合并指定的多个分区到目标分区。
--合并多个指定分区。 ALTER TABLE intpstringstringstring MERGE if EXISTS PARTITION(ds='20181101', hh='00', mm='00'), PARTITION(ds='20181101', hh='10', mm='00'), partition(ds='20181101', hh='10', mm='10') overwrite partition(ds='20181101', hh='00', mm='00') purge; --查看分区表的分区。 SHOW partitions intpstringstringstring; ds=20181101/hh=00/mm=00
清空分区数据
清空分区表中指定分区的数据。
MaxCompute支持通过条件筛选方式清空分区数据。如果您希望一次性删除符合某个规则条件的一个或多个分区,可以使用表达式指定筛选条件,通过筛选条件匹配分区并批量清空分区数据。
命令格式
未指定筛选条件
TRUNCATE TABLE <table_name> PARTITION <pt_spec>[, PARTITION <pt_spec>....];
指定筛选条件
TRUNCATE TABLE <table_name> PARTITION <partition_filtercondition>;
参数说明
参数
是否必填
说明
table_name
是
待清空分区数据的分区表名称。
pt_spec
是
待清空数据的分区。格式为:
(partition_col1 = partition_col_value1, partition_col2 = partition_col_value2, ...)
。其中partition_col是分区字段,partition_col_value是分区值。分区字段不区分大小写,分区值区分大小写。partition_filtercondition
否
指定筛选条件时必填。分区筛选条件,不区分大小写。格式如下:
partition_filtercondition : PARTITION (<partition_col> <relational_operators> <partition_col_value>) | PARTITION (scalar(<partition_col>) <relational_operators> <partition_col_value>) | PARTITION (<partition_filtercondition1> AND|OR <partition_filtercondition2>) | PARTITION (NOT <partition_filtercondition>) | PARTITION (<partition_filtercondition1>)[,PARTITION (<partition_filtercondition2>), ...]
介绍如下:
partition_col:分区名称。
relational_operators:关系运算符,详情请参见运算符。
partition_col_value:分区列比较值或正则表达式,与分区列数据类型保持一致。
scalar():Scalar函数。Scalar函数基于输入值生成对应的标量,对分区列的值(partition_col)进行处理后再按照指定的关系运算符relational_operators与partition_col_value做比较。
分区过滤条件支持逻辑运算符NOT、AND和OR。支持通过NOT过滤条件子句,取过滤规则的补集。支持多个过滤条件子句以AND或OR的关系组成整体分区匹配规则。
支持多个分区过滤子句,当多个分区过滤子句以英文逗号(,)分隔时,每个过滤子句的逻辑以OR的关系组成整体分区匹配规则。
使用示例
未指定筛选条件
--从表sale_detail中清空一个分区,清空2013年12月杭州地域的销售记录。 TRUNCATE TABLE sale_detail PARTITION(sale_date='201312',region='hangzhou'); --从表sale_detail中同时清空两个分区,清空2013年12月杭州和上海地域的销售记录。 TRUNCATE TABLE sale_detail PARTITION(sale_date='201312',region='hangzhou'), PARTITION(sale_date='201312',region='shanghai');
指定筛选条件
--从表sale_detail中清空多个分区,清空杭州地域下sale_date以2013开头的销售记录。 TRUNCATE TABLE sale_detail PARTITION(sale_date LIKE '2013%' AND region='hangzhou');
清空Delta Table非分区表
--清空非分区表,表类型必须为非分区表, 否则报错 TRUNCATE TABLE mf_tt2;
相关文档
更多关于表操作命令详情,请参见: