MaxCompute は、自動パーティション (AUTO PARTITION) テーブルをサポートしています。自動パーティションテーブルのパーティション列は、時間計算関数またはデータ書き込み時間に基づいて自動的に生成できます。このトピックでは、時間計算関数に基づいて生成される自動パーティションテーブルの使用方法について説明します。
概要
MaxCompute は、通常のパーティションテーブルと自動パーティション (AUTO PARTITION) テーブルの 2 種類のパーティションテーブルをサポートしています。さまざまなシナリオでパーティション列を生成する方法に応じて、テーブルタイプを選択できます。詳細については、「パーティションテーブルの概要」をご参照ください。
日付/時刻型の列に基づくパーティショニングや、これらの列を切り捨てた後のパーティショニングをサポートする他のビッグデータプロダクトと比較して、MaxCompute はより柔軟なパーティショニング機能を提供します。MaxCompute は、時刻/日付型のデータ列 (DATE、DATETIME、TIMESTAMP、TIMESTAMP_NTZ) に対して特定の時間計算関数を使用し、データ列の計算結果に基づいてパーティション列の値を自動的に生成することで、テーブルパーティショニングを実装することをサポートしています。
さらに、MaxCompute は、データが書き込まれた時刻を自動的に取得し、ユーザーが指定した時間計算関数と組み合わせて、計算結果に基づいてパーティション列の値を生成し、テーブルのパーティション分割を行うこともサポートしています。詳細については、「データ書き込み時間に基づく自動パーティションテーブル」をご参照ください。
制限事項
時間計算関数に基づく自動パーティションテーブルは、現在 1 つのパーティション列のみをサポートしており、多階層パーティショニングはサポートしていません。
時間計算関数に基づく自動パーティションテーブルのパーティション列は、テーブル作成時に指定されたパーティション生成式に従って自動的に生成されます。パーティションフィールドの型はデフォルトで STRING であり、変更することはできません。
時間関数またはデータ書き込み時間に基づく自動パーティション分割は、MaxCompute SQL を使用してデータを書き込む場合にのみサポートされます。この機能は、Flink コネクタの使用など、他のデータ書き込みメソッドではサポートされていません。
使用上の注意
時間計算関数に基づく自動パーティションテーブルの作成
構文
時間計算関数に基づいて自動パーティションテーブルを作成します。
CREATE [OR REPLACE] TABLE [IF NOT EXISTS] <table_name> (<col_name> <data_type>, ... )
[COMMENT <table_comment>]
AUTO PARTITIONED BY (<auto_partition_expression> [AS <auto_partition_column_name>]);パラメーター
パラメーター | 必須 | 説明 |
table_name | はい | 作成するテーブルの名前。 |
col_name | はい | 列名。 |
data_type | はい | 列のデータ型。 |
table_comment | いいえ | テーブルのコメント。 |
auto_partition_expression | はい | パーティション列の計算方法を定義する式。現在、パーティション列の計算を生成するためにサポートされているのは TRUNC_TIME 関数のみです。 説明 データ書き込み時間に基づいて自動パーティションテーブルを作成する場合、システムはデータ書き込み時間を自動的に取得し、TRUNC_TIME 関数を使用してそれを切り捨て、パーティション列の値を生成します。 |
auto_partition_column_name | いいえ | 生成されるパーティション列の名前。パーティション列名が指定されていない場合、システムはデフォルトの列名として 説明 パーティション式を使用してパーティション分割した後、計算結果に基づいて STRING 型のパーティション列が生成されます。列の型と列の値は直接の操作をサポートしていません。 |
例
例 1: 時刻/日付型の列データを日単位で切り捨てて、自動パーティションを計算および生成します。
TIMESTAMP 型の時間データ列
sale_timeを含む自動パーティションテーブルsale_detailを作成します。DDL 文で、この列データを日単位で切り捨て、計算結果に基づいて AUTO PARTITION テーブルのパーティションを生成します。CREATE TABLE IF NOT EXISTS sale_detail( shop_name STRING, total_price DOUBLE, sale_time TIMESTAMP ) AUTO PARTITIONED BY (TRUNC_TIME(sale_time, 'day'));この文で作成された
sale_detail自動パーティションテーブルには、shop_name、total_price、sale_time、_pt_col_0_の 4 つのカラムが含まれています。_pt_col_0_カラムは自動的に生成されたパーティション列で、そのデータの型は STRING です。DESC sale_detail;文を実行して、テーブル情報を表示できます。 以下は結果の例です:+------------------------------------------------------------------------------------+ | Owner: ALIYUN$*** | | Project: *** | | TableComment: | +------------------------------------------------------------------------------------+ | CreateTime: 2025-06-26 11:21:55 | | LastDDLTime: 2025-06-26 11:21:55 | | LastModifiedTime: 2025-06-26 11:21:55 | +------------------------------------------------------------------------------------+ | InternalTable: YES | Size: 0 | +------------------------------------------------------------------------------------+ | Native Columns: | +------------------------------------------------------------------------------------+ | Field | Type | Label | Comment | +------------------------------------------------------------------------------------+ | shop_name | string | | | | total_price | double | | | | sale_time | timestamp | | | +------------------------------------------------------------------------------------+ | Partition Columns: | +------------------------------------------------------------------------------------+ | _pt_col_0_ | string | | +------------------------------------------------------------------------------------+説明AUTO PARTITION 列のパーティション生成計算ロジックを表示するには、SHOW CREATE TABLE を使用できます。
例 2: 生成されるパーティション列の名前を明示的に指定します。
例 1 に基づいて、明示的に指定されたパーティション列名
sale_dateを追加して、自動パーティションテーブルsale_detail2を作成します。CREATE TABLE IF NOT EXISTS sale_detail2( shop_name STRING, total_price DOUBLE, sale_time TIMESTAMP ) AUTO PARTITIONED BY (TRUNC_TIME(sale_time, 'day') AS sale_date);例 3: TRUNC_TIME 関数の入力データ列が DATE データ型で、日単位でパーティション分割されている場合、次の簡略化された構文がサポートされます。
CREATE TABLE IF NOT EXISTS sale_detail3( shop_name STRING, total_price DOUBLE, sale_date DATE ) AUTO PARTITIONED BY (TRUNC_TIME(sale_date , 'day')); -- 上記の SQL 文は次のように簡略化できます CREATE TABLE IF NOT EXISTS sale_detail3( shop_name STRING, total_price DOUBLE, sale_date DATE ) AUTO PARTITIONED BY (sale_date);重要この簡略化された構文は DATE データ型のみをサポートし、DATETIME/TIMESTAMP/TIMESTAMP_NTZ データ型はサポートしていません。
時間計算関数に基づく自動パーティションテーブルへのデータ書き込み
ユーザーが SQL 文を使用して AUTO PARTITION テーブルにデータを書き込むと、システムはテーブル作成時に指定されたパーティション定義に基づいて計算式を自動的に生成し、テーブル内のデータに基づいて対応するパーティション値を決定します。ユーザーはパーティション値を明示的に指定することはできません。
例: 時間計算関数に基づいて作成されたパーティションテーブル sale_detail2 にデータを書き込みます。
-- プロジェクトのローカルタイムゾーンを東八区に設定します。
set odps.sql.timezone=Asia/Shanghai;
-- 上記のパーティションテーブル sale_detail2 の作成方法と同じです。
CREATE TABLE IF NOT EXISTS sale_detail2(
shop_name STRING,
total_price DOUBLE,
sale_time TIMESTAMP )
AUTO PARTITIONED BY (TRUNC_TIME(sale_time, 'day') AS sale_date);
INSERT INTO sale_detail2 VALUES
('chongqin_shop',101101,timestamp '2025-02-04 01:15:30'),
('shenzhen_shop',202202,timestamp '2024-03-29 15:30:30'),
('hangzhou_shop',303303,timestamp '2025-02-04 08:30:30'),
('shanghai_shop',404404,timestamp '2025-02-28 01:50:30');
この例では、sale_time 時刻データ列の値と、TRUNC_TIME 計算後に生成されるパーティション値の対応は次のとおりです。
sale_time 列 - Asia/Shanghai タイムゾーン | パーティション列 sale_date の値 (時間列を日単位に切り捨てた後に生成され、UTC 時間を表します) |
2025-02-04 01:15:30 | 2025-02-03 |
2024-03-29 15:30:30 | 2024-03-29 |
2025-02-04 08:30:30 | 2025-02-04 |
2025-02-28 01:50:30 | 2025-02-27 |
DATETIME/TIMESTAMP などのタイムゾーン関連のデータ型の場合、TRUNC_TIME は切り捨て前にローカル時刻を UTC 時刻に変換することに注意してください。
この例では、
set odps.sql.timezone=Asia/Shanghai;を使用してプロジェクトのローカルタイムゾーンが東八区に設定されています。タイムゾーンは、TRUNC_TIME の切り捨てによって生成されるパーティション値に影響します。
時間計算関数に基づく自動パーティションテーブルのクエリ
例 1:
select *クエリを実行すると、生成されたパーティション列はデフォルトで表示されません。-- 全表スキャンを有効にする set odps.sql.allow.fullscan=true; SELECT * FROM sale_detail2; -- 結果 +------------+-------------+------------+ | shop_name | total_price | sale_time | +------------+-------------+------------+ | hangzhou_shop | 303303.0 | 2025-02-04 08:30:30 | | shanghai_shop | 404404.0 | 2025-02-28 01:50:30 | | shenzhen_shop | 202202.0 | 2024-03-29 15:30:30 | | chongqin_shop | 101101.0 | 2025-02-04 01:15:30 | +------------+-------------+------------+例 2: 出力に生成されたパーティション列を表示するには、
SELECT *,sale_date from sale_detail2;を実行します。sale_date列は、テーブルの作成時に指定されたパーティション列の名前です。SELECT *,sale_date from sale_detail2; -- 結果 +------------+-------------+------------+------------+ | shop_name | total_price | sale_time | sale_date | +------------+-------------+------------+------------+ | shanghai_shop | 404404.0 | 2025-02-28 01:50:30 | 2025-02-27 | | hangzhou_shop | 303303.0 | 2025-02-04 08:30:30 | 2025-02-04 | | shenzhen_shop | 202202.0 | 2024-03-29 15:30:30 | 2024-03-29 | | chongqin_shop | 101101.0 | 2025-02-04 01:15:30 | 2025-02-03 | +------------+-------------+------------+------------+
時間計算関数に基づく自動パーティションテーブルのパーティションプルーニング
自動パーティションテーブルをクエリする場合、パーティションプルーニングは次のシナリオでのみサポートされます。
Logview で SQL 実行計画を確認するか、EXPLAIN コマンドを使用して、パーティションプルーニングが機能しているかどうかを判断できます。詳細については、「パーティションプルーニングの有効性の評価」をご参照ください。
シナリオ 1: 生成されたパーティション列をフィルター条件として使用する場合、クエリ実行中にパーティションプルーニングがサポートされます。
テーブル sale_detail2 では、クエリ時に生成されたパーティション列 sale_date を通じてデータをフィルターできます。フィルター条件 WHERE sale_date > '2025-02-03'; を使用すると、フィルター条件 sale_date > '2025-02-03' を満たすパーティションのみがスキャンされます。
SELECT * FROM sale_detail2 WHERE sale_date > '2025-02-03';
-- 結果
+------------+-------------+------------+
| shop_name | total_price | sale_time |
+------------+-------------+------------+
| shanghai_shop | 404404.0 | 2025-02-28 01:50:30 |
| hangzhou_shop | 303303.0 | 2025-02-04 08:30:30 |
+------------+-------------+------------+シナリオ 2: パーティション列を生成する時刻/日付型のデータ列 (この列に関数を適用しない) をフィルター条件として使用する場合、クエリ実行中にパーティションプルーニングがサポートされます。
テーブル sale_detail2 では、テーブル内の時刻データ列 sale_time を通じてデータをフィルターできます。フィルター条件 WHERE sale_time > '2025-02-04 08:00:00'; を使用すると、システムはどのパーティションデータが sale_time のスキャン条件を満たすかを判断し、条件を満たす対応するパーティションのみをスキャンします。
SELECT * FROM sale_detail2 WHERE sale_time > '2025-02-04 08:00:00';
-- 結果
+------------+-------------+------------+
| shop_name | total_price | sale_time |
+------------+-------------+------------+
| shanghai_shop | 404404.0 | 2025-02-28 01:50:30 |
| hangzhou_shop | 303303.0 | 2025-02-04 08:30:30 |
+------------+-------------+------------+シナリオ 3: テーブル作成時にパーティション列の生成に使用された時刻/日付型のデータ列に関数計算を適用し、その計算結果をフィルター条件として使用する場合。現在、一部の関数計算シナリオでパーティションプルーニングがサポートされています。
パーティションプルーニングをサポートする関数 | パーティションプルーニングが有効になる条件 |
時間の切り捨て粒度がテーブル作成文と同じ場合にパーティションプルーニングがサポートされます。 | |
時間の切り捨て粒度がテーブル作成文と同じ場合にパーティションプルーニングがサポートされます。 | |
CAST AS DATE | テーブル作成時のパーティション生成の切り捨て粒度が日単位の場合にパーティションプルーニングがサポートされます。 |
テーブル作成時のパーティション生成の切り捨て粒度が日単位の場合にパーティションプルーニングがサポートされます。 |
例 1: タイムゾーンパラメーターなしで TRUNC_TIME 関数または DATETRUNC 関数を使用して
sale_time時間列をフィルター処理し、時間の切り捨て粒度がテーブル作成文の粒度と同じである場合、パーティションプルーニングが有効になります。SELECT * FROM sale_detail2 WHERE TRUNC_TIME(sale_time, 'day') > '2025-02-04'; SELECT * FROM sale_detail2 WHERE DATETRUNC(sale_time, 'dd') > '2025-02-04 00:00:00'; -- 結果 +------------+-------------+------------+ | shop_name | total_price | sale_time | +------------+-------------+------------+ | shanghai_shop | 404404.0 | 2025-02-28 01:50:30 | +------------+-------------+------------+例 2: パーティションプルーニングは、
sale_time列を CAST AS DATE または TO_DATE 関数 (タイムゾーン パラメーターなし) を使用してフィルターする場合に有効です。これを有効にするには、テーブル作成時に指定された切り捨ての粒度が `day` である必要があります。SELECT * FROM sale_detail2 WHERE CAST(sale_time AS date) = '2025-02-04'; SELECT * FROM sale_detail2 WHERE TO_DATE(sale_time) = '2025-02-04'; -- 結果 +------------+-------------+------------+ | shop_name | total_price | sale_time | +------------+-------------+------------+ | hangzhou_shop | 303303.0 | 2025-02-04 08:30:30 | +------------+-------------+------------+