分区操作

更新时间:
复制为 MD 格式

MaxCompute支持对已有表的分区执行变更操作,如添加分区、删除分区、修改分区值等,可以根据实际业务场景执行相应操作。

功能索引

MaxCompute SQL的分区操作命令如下。

操作

功能

角色

操作入口

添加分区

为已存在的分区表新增分区。

具备修改表权限(Alter)的用户

本文中的命令可以在如下工具平台执行:

修改分区的更新时间

修改分区表中分区的LastModifiedTime

修改分区值

修改分区表的分区值。

合并分区

对分区表的分区进行合并,即同一个分区表下的多个分区合并成一个分区,同时删除被合并的分区维度的信息,并将数据移动到指定分区。

列出所有分区

列出一张表中的所有分区。

查看分区信息

查看某个分区表具体的分区的信息。

删除分区

为已存在的分区表删除分区。

清空分区数据

清空指定分区的数据。

适用范围

  • 数据类型:目前支持将TINYINT、SMALLINT、INT、BIGINT、CHAR、VARCHARSTRING数据类型的字段设为分区列。

  • 单表分区层级最多6级。

  • 单表分区数最多允许60000个分区。

  • 一次最多查询分区数10000个。

  • Transaction类型的分区表不支持merge partition操作。

添加分区

为已存在的分区表新增分区。

  • 限制条件

    • 对于有多级分区的表,如果需要添加新的分区值,必须指明全部的分区。

    • 仅支持新增分区值,不支持新增分区字段。

  • 命令格式

    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是分区值。分区字段不区分大小写,分区值区分大小写。

  • 使用示例

    创建普通分区表sale_detail,创建和删除表,详情请参见创建和删除表

    CREATE TABLE IF NOT EXISTS sale_detail(
     shop_name     STRING,
     customer_id   STRING,
     total_price   DOUBLE)
    PARTITIONED BY (sale_date STRING, region STRING);
    • 示例1:给表sale_detail添加一个分区,用来存储202512月杭州地区的销售记录。

      ALTER TABLE sale_detail ADD IF NOT EXISTS PARTITION (sale_date='202512', region='hangzhou');
    • 示例2:给表sale_detail同时添加两个分区,用来存储202512月北京和上海地区的销售记录。

      ALTER TABLE sale_detail ADD IF NOT EXISTS PARTITION (sale_date='202512', region='beijing') PARTITION (sale_date='202512', region='shanghai');
    • 示例3:给表sale_detail添加分区,仅指定一个分区字段sale_date,返回报错,需要同时指定2个分区字段sale_dateregion

      ALTER TABLE sale_detail ADD IF NOT EXISTS PARTITION (sale_date='20260111');
      
      -- 错误信息如下:
      FAILED: ODPS-0130071:[1,58] Semantic analysis exception - provided partition spec does not match table partition spec
    • 示例4:增加Delta Table表分区

      -- 创建Delta Table表
      CREATE TABLE delta_table_test_par (
        pk BIGINT NOT NULL PRIMARY KEY, 
        val BIGINT NOT NULL) 
        PARTITIONED BY (dd STRING, hh STRING) 
        TBLPROPERTIES ("transactional"="true"); 
                   
      -- 添加分区           
      ALTER TABLE delta_table_test_par ADD PARTITION (dd='01', hh='01');
      
      CREATE TABLE delta_table_test_nonpar (
        pk BIGINT NOT NULL PRIMARY KEY, 
        val BIGINT NOT NULL) 
        TBLPROPERTIES ("transactional"="true");
    • 示例5:修改PK Delta Table表属性

      -- PK Delta Table分区表更新bucket数。
      ALTER TABLE delta_table_test_par SET tblproperties("write.bucket.num"="64");
      
      -- PK Delta Table非分区表更新bucket数,修改后存量数据会按照新bucket数重新分布。
      ALTER TABLE delta_table_test_nonpar REWRITE tblproperties("write.bucket.num"="128");
      
      -- 更新retain属性,表示TimeTravel可查询数据历史状态的时间范围(单位为小时)。
      ALTER TABLE delta_table_test_par SET tblproperties("acid.data.retain.hours"="60");

修改分区的更新时间

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='202512', region='shanghai'的LastModifiedTime。
    ALTER TABLE sale_detail touch PARTITION (sale_date='202512', 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条件的分区,则不生成新分区。如果运行过程中出现源数据被并发修改(包括insertrenamedrop)时,即使指定IF EXISTS也会报错。

    predicate

    筛选待合并分区需要满足的条件。

    fullpartitionSpec

    目标分区信息。

    purge

    可选关键字。选择该字段,则会清理session目录,默认清理3天内的日志。详情请参见Purge

  • 使用示例

    • 示例1:合并满足指定条件的分区到目标分区。

      -- 查看分区表的分区。
      SHOW PARTITIONS sale_detail;
      
      -- 示例返回结果:
      sale_date=202512/region=beijing
      sale_date=202512/region=shanghai
      sale_date=202602/region=beijin
      
      --合并所有满足sale_date='201512'的分区到sale_date='202601',region='hangzhou'中。
      ALTER TABLE sale_detail MERGE PARTITION(sale_date='202512') overwrite PARTITION(sale_date='202601', region='hangzhou');
      
      --查看合并后的分区。
      SHOW PARTITIONS sale_detail;
      
      -- 示例返回结果:
      sale_date=202601/region=hangzhou
      sale_date=202602/region=beijing                   
    • 示例2:合并指定的多个分区到目标分区。

      -- 合并多个指定分区。
      ALTER TABLE sale_detail MERGE IF EXISTS 
        PARTITION(sale_date='202601', region='hangzhou'), 
        PARTITION(sale_date='202602', region='beijing') 
        overwrite PARTITION(sale_date='202603', region='shanghai') purge;
      
      -- 查看分区表的分区。
      SHOW PARTITIONS sale_detail;
      
      -- 示例返回结果:
      sale_date=202603/region=shanghai

列出所有分区

列出一张表中的所有分区。当表不存在或为非分区表时,返回报错。

  • 命令格式

    SHOW PARTITIONS <table_name>; 
  • 参数说明

    table_name:必填。待查看分区信息的分区表名称。

  • 使用示例

    -- 列出sale_detail中的所有分区。
    SHOW PARTITIONS sale_detail;
    
    -- 示例返回结果:
    sale_date=202603/region=shanghai

查看分区信息

查看某个分区表具体的分区的信息。

  • 命令格式

    DESC <table_name> PARTITION (<pt_spec>);
  • 参数说明

    参数

    是否必填

    说明

    table_name

    待查看分区信息的分区表名称。

    pt_spec

    待查看的分区信息。格式为partition_col1=col1_value1, partition_col2=col2_value1...。对于有多级分区的表,必须指明全部的分区值。

  • 使用示例

    -- 查询分区表sale_detail的分区信息。
    DESC sale_detail PARTITION (sale_date='202603',region='shanghai');
    -- 返回结果如下:
    +------------------------------------------------------------------------------------+
    | PartitionSize: 0                                                                   |
    +------------------------------------------------------------------------------------+
    | CreateTime:               2026-01-13 11:35:49                                      |
    | LastDDLTime:              2026-01-13 11:35:49                                      |
    | LastModifiedTime:         2026-01-13 11:35:49                                      |
    +------------------------------------------------------------------------------------+
    
    OK

删除分区

为已存在的分区表删除分区。

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_operatorspartition_col_value做比较。

    • 分区过滤条件支持逻辑运算符NOT、ANDOR。支持通过NOT过滤条件子句,取过滤规则的补集。支持多个过滤条件子句以ANDOR的关系组成整体分区匹配规则。

    • 支持多个分区过滤子句,当多个分区过滤子句以英文逗号(,)分隔时,每个过滤子句的逻辑以OR的关系组成整体分区匹配规则。

  • 使用示例

    • 未指定筛选条件

      -- 从表sale_detail中删除一个分区,20263月上海分区的销售记录。
      ALTER TABLE sale_detail DROP IF EXISTS PARTITION(sale_date='202603',region='shanghai'); 
      -- 从表sale_detail中同时删除两个分区,202412月杭州和上海分区的销售记录。
      ALTER TABLE sale_detail DROP IF EXISTS PARTITION(sale_date='202412',region='hangzhou'),PARTITION(sale_date='202412',region='shanghai');
    • 指定筛选条件

      • 分区表

        -- 创建分区表
        CREATE TABLE IF NOT EXISTS sale_detail_del(
        shop_name     STRING,
        customer_id   STRING,
        total_price   DOUBLE)
        partitioned BY (sale_date STRING);
        
        -- 添加分区
        ALTER TABLE sale_detail_del 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_del DROP IF EXISTS PARTITION(sale_date < '201911');
        ALTER TABLE sale_detail_del DROP IF EXISTS PARTITION(sale_date >= '202007');
        ALTER TABLE sale_detail_del DROP IF EXISTS PARTITION(sale_date LIKE '20191%');
        ALTER TABLE sale_detail_del DROP IF EXISTS PARTITION(sale_date IN ('202002','202004','202006'));
        ALTER TABLE sale_detail_del DROP IF EXISTS PARTITION(sale_date BETWEEN '202001' AND '202007');
        ALTER TABLE sale_detail_del DROP IF EXISTS PARTITION(substr(sale_date, 1, 4) = '2020');
        ALTER TABLE sale_detail_del DROP IF EXISTS PARTITION(sale_date < '201912' OR sale_date >= '202006');
        ALTER TABLE sale_detail_del DROP IF EXISTS PARTITION(sale_date > '201912' AND sale_date <= '202004');
        ALTER TABLE sale_detail_del DROP IF EXISTS PARTITION(NOT sale_date > '202004');
        
        -- 支持多个分区过滤表达式,表达式之间是OR的关系
        ALTER TABLE sale_detail_del DROP IF EXISTS PARTITION(sale_date < '201911'), PARTITION(sale_date >= '202007');
        
        -- 添加其他格式分区
        ALTER TABLE sale_detail_del 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_del 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小于201911region等于beijing的分区都删除掉。
        ALTER TABLE region_sale_detail DROP IF EXISTS PARTITION(sale_date < '201911'),PARTITION(region = 'beijing');
        
        -- 如果删除sale_date小于201911region等于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支持通过条件筛选方式清空分区数据。如果您希望一次性删除符合某个规则条件的一个或多个分区,可以使用表达式指定筛选条件,通过筛选条件匹配分区并批量清空分区数据。

  • 命令格式

    • 未指定筛选条件

      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_operatorspartition_col_value做比较。

    • 分区过滤条件支持逻辑运算符NOT、ANDOR。支持通过NOT过滤条件子句,取过滤规则的补集。支持多个过滤条件子句以ANDOR的关系组成整体分区匹配规则。

    • 支持多个分区过滤子句,当多个分区过滤子句以英文逗号(,)分隔时,每个过滤子句的逻辑以OR的关系组成整体分区匹配规则。

  • 使用示例

    • 未指定筛选条件

      -- 从表sale_detail中清空一个分区,清空202601月杭州地域的销售记录。
      TRUNCATE TABLE sale_detail PARTITION(sale_date='202601',region='hangzhou');
      
      -- 从表sale_detail中同时清空两个分区,清空202512月杭州和上海地域的销售记录。
      TRUNCATE TABLE sale_detail PARTITION(sale_date='202512',region='hangzhou'),  PARTITION(sale_date='202512',region='shanghai');
    • 指定筛选条件

      -- 从表sale_detail中清空多个分区,清空杭州地域下sale_date2025开头的销售记录。
      TRUNCATE TABLE sale_detail PARTITION(sale_date LIKE '2025%' AND region='hangzhou');
    • 清空Delta Table非分区表

      -- 清空非分区表,表类型必须为非分区表, 否则报错
      TRUNCATE TABLE non_par_table; 

相关文档

更多关于表操作命令详情,请参见: