全部產品
Search
文件中心

MaxCompute:基於資料寫入時間的自動分區表

更新時間:Dec 16, 2025

MaxCompute支援在資料寫入時自動擷取寫入時間,並結合使用者指定的時間計算函數(TRUNC_TIME),根據計算結果產生分區列的值,從而實現對錶的分區。這種基於資料寫入時間的自動分區表又稱為Ingestion Time Partition表,本文將介紹基於資料寫入時間的自動分區表的使用方法。

功能介紹

MaxCompute支援普通分區表和自動分區表(AUTO PARTITION)兩種分區表類型,可根據不同情境下預期的分區列產生方式,選擇不同的分區表類型。詳情請參見分區表概述

使用Ingestion Time Partition表時,需要指定一個名為_partitiontime、資料類型為時間類型的列。系統會按照一定的時間粒紋,對每行資料的寫入時間進行截取(如:按小時、按天、按月、按年),然後自動產生_partitiontime列值。

例如,使用者建立了一個按小時截取產生分區的Ingestion Time Partition表,並在以下時間寫入資料:

資料寫入時間(UTC+8)

產生的 _PARTITIONTIME列(TIMESTAMP類型)

產生的分區(STRING類型)

2025-06-18 17:22:00

2025-06-18 17:00:00

2025-06-18 09:00:00

2025-06-18 17:40:00

2025-06-18 17:00:00

2025-06-18 09:00:00

2025-06-18 18:31:00

2025-06-18 18:00:00

2025-06-18 10:00:00

上述樣本中,Ingestion Time Partition表指定按小時截取產生分區,因此,_partitiontime列會根據資料寫入時間進行截取並產生對應的值,並將該值轉換為UTC時間後的STRING類型值,作為資料所在的分區。

使用限制

  • 基於資料寫入時間的自動分區表當前僅支援一個分區列,且不支援多級分區。

  • 基於資料寫入時間的自動分區表的分區列,欄位類型預設為STRING,不支援修改。

  • 基於時間計算函數和資料寫入時間的Auto Partition能力僅在基於MaxCompute SQL寫入時支援,不支援其他資料寫入方式如Flink Connector。

  • 按照資料寫入時間進行截斷時,當前僅支援TRUNC_TIME函數,該函數會將本地時間轉換為UTC時間再進行截斷。因此最終產生的STRING類型分區列的值會受到時區影響。建議執行SET odps.sql.timezone=UTC;語句調整專案的本地時區為UTC時區。

使用說明

建立Ingestion Time Partition表

文法結構

建立基於資料寫入時間的自動分區表。

CREATE [OR REPLACE] TABLE [IF NOT EXISTS] <table_name> (_partitiontime <data_type>, <col_name><data_type>... )
[COMMENT <table_comment>]
AUTO PARTITIONED BY (<auto_partition_expression> [AS <auto_partition_column_name>]);
TBLPROPERTIES('ingestion_time_partition'='true');

參數說明如下:

參數

是否必填

描述

table_name

待建立的表名。

_partitiontime

按資料寫入時間截取產生的時間偽列,列名不支援修改,資料類型僅支援TIMESTAMP、TIMESTAMP_NTZ。

col_name

列名。

data_type

列資料類型。

table_comment

表注釋。

TBLPROPERTIES('ingestion_time_partition'='true')

指定所建立的表為基於資料寫入時間的自動分區表(Ingestion Time Partition表),按資料寫入時間產生分區列。

auto_partition_expression

定義如何進行分區列計算的運算式。當前僅支援使用TRUNC_TIMEFunction Compute_partitiontime時間偽列,以產生分區列。

說明

當建立基於資料寫入時間的自動分區表時,系統會自動擷取資料寫入時間,並通過TRUNC_TIME函數對寫入時間進行截取,從而產生分區列的值。

auto_partition_column_name

產生分區列的列名,若未指定分區列的列名,則系統會以_pt_col_0_為預設列名,依次檢查表中是否存在該列名,若存在則自動遞增尾碼(如_pt_col_1__pt_col_2_等),直到找到未被佔用的列名為止。

說明

使用分區運算式進行分區計算後,會根據計算結果產生一個STRING類型的分區列,列的類型和列的取值均不支援直接操作

使用樣本

  • 樣本1

    建立一張按小時分區,表名為ingestion_sale_detail_hourly的Ingestion Time Partition表,表中指定一個TIMESTAMP類型時間偽列_partitiontime。當資料寫入時,系統會自動擷取資料寫入時間,並根據DDL語句中按小時作為截取粒度產生_partitiontime列的值,然後基於計算結果產生表的分區sale_time

    -- 表建立完成後,當資料寫入時系統會自動擷取資料寫入時間,按小時為粒度進行截取計算_partitiontime,並產生名為sale_time的分區列,並根據該分區列進行表的分區
    CREATE TABLE IF NOT EXISTS ingestion_sale_detail_hourly(
     shop_name     STRING,
     total_price   DOUBLE,
     _partitiontime TIMESTAMP)
    AUTO PARTITIONED BY (TRUNC_TIME(_partitiontime, 'hour') AS sale_time)
    TBLPROPERTIES('ingestion_time_partition'='true');

    上述建立的ingestion_sale_detail_hourly表包含4列,其中 sale_time是自動產生的一個STRING類型的分區列。可執行DESC ingestion_sale_detail_hourly;語句查看錶資訊,返回結果樣本如下:

    +------------------------------------------------------------------------------------+
    | Owner:                    ALIYUN$test****                                          |
    | Project:                   xxxxxxx                                                 |
    | Schema:                    default                                                 |
    | TableComment:                                                                      |
    +------------------------------------------------------------------------------------+
    | CreateTime:               2025-06-16 14:59:40                                      |
    | LastDDLTime:              2025-06-16 14:59:40                                      |
    | LastModifiedTime:         2025-06-16 14:59:40                                      |
    +------------------------------------------------------------------------------------+
    | InternalTable: YES      | Size: 0                                                  |
    +------------------------------------------------------------------------------------+
    | Native Columns:                                                                    |
    +------------------------------------------------------------------------------------+
    | Field           | Type       | Label | Comment                                     |
    +------------------------------------------------------------------------------------+
    | shop_name       | string     |       |                                             |                                        |
    | total_price     | double     |       |                                             |
    | _partitiontime  | timestamp  |       |                                             |
    +------------------------------------------------------------------------------------+
    | Partition Columns:                                                                 |
    +------------------------------------------------------------------------------------+
    | sale_time       | string     |                                                     |
    +------------------------------------------------------------------------------------+
  • 樣本2

    建立一張按天分區,表名為ingestion_sale_detail_daily的Ingestion Time Partition表。當表的分區產生截取粒度為按天時,除了_partitiontime之外,會額外產生一個DATE類型的偽列_partitiondate

    CREATE TABLE IF NOT EXISTS ingestion_sale_detail_daily(
     shop_name     STRING,
     total_price   DOUBLE,
     _partitiontime TIMESTAMP)
    AUTO PARTITIONED BY (TRUNC_TIME(_partitiontime, 'day') AS sale_date)
    TBLPROPERTIES('ingestion_time_partition'='true');
    說明
    • 可通過SELECT *, _partitiondate FROM ingestion_sale_detail_daily;命令查看偽列_partitiondate

    • 如需查看Ingestion Time Partition分區列的分區產生計算邏輯,可以通過SHOW CREATE TABLE進行查看。

寫入Ingestion Time Partition表

當使用SQL語句向Ingestion Time Partition表中寫入資料時,支援指定_partitiontime時間偽列的值,但需保證_partitiontime列值的時間截取粒度與建表語句中定義的一致。

若不指定_partitiontime,則系統會自動擷取資料寫入MaxCompute的時間,結合使用者指定的時間計算函數,根據計算結果產生_partitiontime時間偽列和分區列的值,對資料進行分區。

樣本如下:

說明

下述樣本基於使用樣本中已建立的ingestion_sale_detail_hourlyingestion_sale_detail_daily表,進行資料寫入。

  • 樣本1

    插入資料時,不指定_partitiontime時間偽列的值。

    INSERT INTO ingestion_sale_detail_hourly (shop_name,total_price) 
    VALUES 
      ('shanghai_shop',10001.1), 
      ('chongqin_shop',20002.2), 
      ('hangzhou_shop',30003.3), 
      ('shenzhen_shop',40004.4);
  • 樣本2

    插入資料時,指定 _partitiontime時間偽列的值,需保證寫入的_partitiontime列值與分區產生的指定時間截取粒度(hour)一致。

    • 正確樣本:指定_partitiontime列的值為'2025-06-15 14:00:00'

      INSERT INTO ingestion_sale_detail_hourly (shop_name,total_price,_partitiontime)
      VALUES 
        ('beijing_shop',50005.5,TIMESTAMP '2025-06-15 14:00:00'),
        ('chengdu_shop',60006.6,TIMESTAMP '2025-06-14 05:00:00');
    • 錯誤樣本:指定_partitiontime列的值為'2025-06-15 14:30:00',與分區產生的按小時截取粒度不一致。

      INSERT INTO ingestion_sale_detail_hourly (shop_name,total_price,_partitiontime)
      VALUES ('beijing_shop',50005.5,TIMESTAMP '2025-06-15 14:30:00');

      返回的報錯資訊如下:

      FAILED: ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: SQL Runtime Unretryable Error: ODPS-0121095:Invalid argument - illegal ingestion time: 2025-06-15 14:30:00
  • 樣本3

    當分區產生的截取粒度為按天時,仍然僅支援指定_partitiontime時間偽列的值,不支援指定 _partitiondate日期偽列值。

    • 正確樣本:指定_partitiontime列的值為'2025-06-18 00:00:00'

      INSERT INTO ingestion_sale_detail_daily (shop_name,total_price,_partitiontime) 
      VALUES ('beijing_shop',50005.5,TIMESTAMP '2025-06-18 00:00:00');
    • 錯誤樣本:

      • 指定_partitiontime列的值為'2025-06-15 14:00:00',與分區產生的按天截取粒度不一致。

        INSERT INTO ingestion_sale_detail_daily (shop_name,total_price,_partitiontime) 
        VALUES ('beijing_shop',50005.5,TIMESTAMP '2025-06-18 14:00:00');

        返回的報錯資訊如下:

        FAILED: ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: SQL Runtime Unretryable Error: ODPS-0121095:Invalid argument - illegal ingestion time: 2025-06-18 14:00:00
      • 直接指定_partitiondate偽列的值。

        INSERT INTO ingestion_sale_detail_daily (shop_name,total_price,_partitiondate) 
        VALUES ('beijing_shop',50005.5,DATE '2025-06-15');

        返回的錯誤資訊如下:

        FAILED: ODPS-0130071:[1,64] Semantic analysis exception - column _partitiondate cannot be resolved; Did you mean _partitiontime ?

查詢Ingestion Time Partition表

  • 執行SELECT *的查詢語句時,系統預設不顯示_partitiontime_partitiondate偽列及產生的分區列。若希望顯示,則需在語句中顯式指定對應的列,例如SELECT *, _partitiontime FROM xxx;

  • 對於按小時、按月、按年粒度進行截取產生分區的表,可以使用時間類型的偽列_partitiontime進行查詢過濾和分區裁剪。Ingestion Time Partition表作為一種特殊的自動分區表,支援的分區裁剪能力與普通自動分區表一致,詳情請參見基於時間計算函數的自動分區表

樣本如下:

說明

下述樣本基於使用樣本中已建立的ingestion_sale_detail_hourlyingestion_sale_detail_daily表,進行資料查詢。

  • 樣本1

    執行SELECT *的查詢語句時,系統預設不顯示_partitiontime_partitiondate偽列及產生的分區列。

    SELECT *  FROM ingestion_sale_detail_hourly;
    
    -- 返回結果
    +------------+-------------+
    | shop_name  |  total_price |
    +---------------+-------------+
    | shanghai_shop | 10001.1     |
    | chongqin_shop | 20002.2     |
    | hangzhou_shop | 30003.3     |
    | shenzhen_shop | 40004.4     |
    | chengdu_shop  | 60006.6     |
    | beijing_shop  | 50005.5     |
    +---------------+-------------+
  • 樣本2

    查詢時指定顯示_partitiontime_partitiondate偽列及產生的分區列,其中sale_timesale_date是在建立該表時指定的產生分區列的列名。

    說明

    本樣本中通過set odps.sql.timezone=Asia/Shanghai;設定專案本地時區為東八區時區,在TRUNC_TIME截取產生的分區值時,會受到時區影響。

    • 查詢按小時分區的ingestion_sale_detail_hourly表。

      SELECT * ,_partitiontime,sale_time FROM ingestion_sale_detail_hourly;
      
      --返回結果如下
      +---------------+-------------+---------------------+---------------------+
      | shop_name     | total_price | _partitiontime      | sale_time           |
      +---------------+-------------+---------------------+---------------------+
      | shanghai_shop | 10001.1     | 2025-06-18 15:00:00 | 2025-06-18 07:00:00 |
      | chongqin_shop | 20002.2     | 2025-06-18 15:00:00 | 2025-06-18 07:00:00 |
      | hangzhou_shop | 30003.3     | 2025-06-18 15:00:00 | 2025-06-18 07:00:00 |
      | shenzhen_shop | 40004.4     | 2025-06-18 15:00:00 | 2025-06-18 07:00:00 |
      | beijing_shop  | 50005.5     | 2025-06-15 14:00:00 | 2025-06-15 06:00:00 |
      | chengdu_shop  | 60006.6     | 2025-06-14 05:00:00 | 2025-06-13 21:00:00 |
      +---------------+-------------+---------------------+---------------------+
    • 查詢按天分區的ingestion_sale_detail_daily表。

      SELECT * ,_partitiontime,_partitiondate,sale_date FROM ingestion_sale_detail_daily;
      
      --返回結果如下
      +--------------+-------------+---------------------+----------------+-----------+
      | shop_name    | total_price | _partitiontime      | _partitiondate | sale_date |
      +--------------+-------------+---------------------+----------------+-----------+
      | beijing_shop | 50005.5     | 2025-06-18 00:00:00 | 2025-06-18     | 2025-06-18|
      +--------------+-------------+---------------------+----------------+-----------+