すべてのプロダクト
Search
ドキュメントセンター

MaxCompute:動的パーティションへのデータの挿入または上書き (dynamic PARTITION)

最終更新日:Dec 06, 2024

MaxComputeでは、insert intoまたはINSERT OVERWRITEを使用して、動的パーティションにデータを挿入できます。

次のプラットフォームでステートメントを実行できます。

前提条件

INSERT INTOまたはINSERT OVERWRITEステートメントを実行する前に、ターゲットテーブルに対するUpdate権限と、ソーステーブルのメタデータに対するSelect権限が付与されていることを確認してください。 詳細は、「MaxCompute権限」をご参照ください。

説明

MaxCompute SQLを使用してデータを処理する場合、パーティションキー列の値ではなく、INSERT INTOまたはINSERT OVERWRITEのパーティションキー列の名前のみを指定する必要があります。 select_statementでパーティションキー列の値を指定すると、MaxComputeは列の値に基づいて宛先パーティションにデータを自動的に挿入します。

静的パーティションにデータを挿入する方法の詳細については、「テーブルまたは静的パーティションにデータを挿入または更新する (insert intoおよびInsert OVERWRITE) 」をご参照ください。

制限事項

insert intoまたはINSERT OVERWRITEを使用して動的パーティションにデータを挿入する場合は、次の制限事項に注意してください。

  • INSERT INTOの実行後、最大10,000個の動的パーティションを生成できます。 INSERT OVERWRITEの実行後、最大60,000個の動的パーティションを生成できます。

  • 分散環境では、動的パーティションにデータを挿入または更新するために使用されるSQL文は、最大512個の動的パーティションを生成できます。 動的パーティションの数がこの制限を超えると、例外が発生します。

  • 動的パーティションの値はNULLにすることはできません。また、特殊文字を含めることはできません。 それ以外の場合、次のエラーが報告されます。FAILED: ODPS-0123031:Partition exception - invalid dynamic partition value: province=xxx

    説明

    パーティションキー列の値には、漢字などの2バイト文字を含めることはできません。 パーティションキー列の値は文字で始まる必要があり、文字、数字、およびサポートされている特殊文字を含めることができます。 長さは1〜255バイトでなければなりません。 次の特殊文字がサポートされています: スペース、コロン (:) 、アンダースコア (_) 、ドル記号 ($) 、数字記号 (#) 、ピリオド (.) 、感嘆符 (!) 、およびアット記号 (@) 。 エスケープ文字 \t\n/など、他の文字の動作は定義されていません。

  • クラスタテーブルは動的パーティションをサポートしません。

注意事項

テーブルデータを動的パーティションに更新する場合は、次の点に注意してください。

  • INSERT INTOまたはINSERT OVERWRITEを使用して、存在しないinsert data into a partitionする場合、MaxComputeは自動的にパーティションを作成します。

  • 複数のジョブを同時に実行して、存在しないinsert data into partitionsする場合、MaxComputeは、正常に実行された最初のジョブのパーティションを自動的に作成します。 ただし、このジョブに対して作成されるパーティションは1つだけです。

  • ジョブの同時実行を制御できない場合は、事前にALTER TABLEコマンドを実行してパーティションを作成することを推奨します。 詳細については、「パーティションと列の操作」をご参照ください。

  • 宛先テーブルに複数のレベルのパーティションがある場合、INSERTステートメントで一部のパーティションを静的パーティションとして指定できます。 ただし、静的パーティションは高レベルのパーティションでなければなりません。

  • 動的パーティションにデータを挿入するには、select_statementでパーティションキー列を指定する必要があります。 そうでない場合、データの挿入に失敗します。

構文

insert {into|overwrite} table <table_name> partition (<ptcol_name>[, <ptcol_name> ...]) 
<select_statement> from <from_statement>;
  • table_name: 必須です。 データを挿入するターゲットテーブルの名前。

  • ptcol_name: 必須です。 ターゲットテーブルのパーティションキー列の名前。

  • select_statement: 必須です。 ソーステーブルからターゲットテーブルに挿入するデータを照会するために使用されるSELECT句。

    ターゲットテーブルにレベル1の動的パーティションしかない場合、select_statementの最後のフィールドの値は、ターゲットテーブルの動的パーティションの値を示します。 select_statementのソーステーブルの列値とターゲットテーブルの列値の間のマッピングは、列名ではなく、列シーケンスによって決まります。 ソーステーブルの列の順序がターゲットテーブルの列の順序と異なる場合は、ターゲットテーブルの列の順序に基づいてselect_文で列を指定することを推奨します。

  • from_statement: 必須です。 FROM句。 この句は、ソーステーブル名などのデータソースを指定します。

  • 例1: ソーステーブルから宛先テーブルにデータを挿入します。 region列に基づいて生成されたパーティションは、ステートメントが実行された後にのみ取得できます。 次のステートメントは例を示します。

    -- Create a destination table named total_revenues. 
    create table total_revenues (revenue double) partitioned by (region string);
    
    -- Insert the data from the sale_detail table into the total_revenues table. For more information about the sale_detail table, see Insert or update data into a table or a static partition (INSERT INTO and INSERT OVERWRITE). 
    set odps.sql.allow.fullscan=true; 
    insert overwrite table total_revenues partition(region)
    select total_price as revenue, region from sale_detail;
    
    -- Execute the SHOW PARTITIONS statement to view the partitions in the total_revenues table. 
    show partitions total_revenues;
       
    -- The following result is returned: 
    region=china  
    
    -- Enable a full table scan only for the current session. Execute the SELECT statement to query data from the total_revenues table.   
    set odps.sql.allow.fullscan=true; 
    select * from total_revenues;    
    
    -- The following result is returned: 
    +------------+------------+
    | revenue    | region     |
    +------------+------------+
    | 100.1      | china      |
    | 100.2      | china      |
    | 100.3      | china      |
    +------------+------------+        
  • 例2: ソーステーブルから宛先テーブルにデータを挿入します。 宛先テーブルに複数のレベルのパーティションがある場合は、レベル1のパーティションsale_dateを指定する必要があります。 次のステートメントは例を示します。

    -- Create a destination table named sale_detail_dypart.  
    create table sale_detail_dypart like sale_detail; 
    
    -- Specify a level-1 partition and insert data into the destination table. 
    insert overwrite table sale_detail_dypart partition (sale_date='2013', region)
    select shop_name,customer_id,total_price,region from sale_detail;
    
    -- Enable a full table scan only for the current session. Execute the SELECT statement to query data from the sale_detail_dypart table. 
    set odps.sql.allow.fullscan=true; 
    select * from sale_detail_dypart;
    
    -- The following result is returned: 
    +------------+-------------+-------------+------------+------------+
    | shop_name  | customer_id | total_price | sale_date  | region     |
    +------------+-------------+-------------+------------+------------+
    | s1         | c1          | 100.1       | 2013       | china      |
    | s2         | c2          | 100.2       | 2013       | china      |
    | s3         | c3          | 100.3       | 2013       | china      |
    +------------+-------------+-------------+------------+------------+
  • 例3: select_statementの列とターゲットテーブルの動的パーティションの列の間のマッピングは、列名ではなく列の順序によって決まります。 次のステートメントは例を示します。

    -- Insert data from the sale_detail table into the sale_detail_dypart table. 
    insert overwrite table sale_detail_dypart partition (sale_date, region)
    select shop_name,customer_id,total_price,sale_date,region from sale_detail;
    
    -- Enable a full table scan only for the current session. Execute the SELECT statement to query data from the sale_detail_dypart table. 
    set odps.sql.allow.fullscan=true; 
    select * from sale_detail_dypart;
    
    -- The following result is returned: The sale_date column in the dynamic partition of the sale_detail_dypart table is determined by the region column in the sale_detail table. The region column in the dynamic partition of the sale_detail_dypart table is determined by the sale_date column in the sale_detail table. 
    +------------+-------------+-------------+------------+------------+
    | shop_name  | customer_id | total_price | sale_date  | region     |
    +------------+-------------+-------------+------------+------------+
    | s1         | c1          | 100.1       | 2013       | china      |
    | s2         | c2          | 100.2       | 2013       | china      |
    | s3         | c3          | 100.3       | 2013       | china      |
    +------------+-------------+-------------+------------+------------+
    
    -- Insert data from the sale_detail table into the sale_detail_dypart table and change the sequence of columns in select_statement. 
    insert overwrite table sale_detail_dypart partition (sale_date, region)
    select shop_name,customer_id,total_price,region,sale_date from sale_detail;
    
    -- Enable a full table scan only for the current session. Execute the SELECT statement to query data from the sale_detail_dypart table. 
    set odps.sql.allow.fullscan=true; 
    select * from sale_detail_dypart;
    
    -- The following result is returned: The sale_date column in the dynamic partition of the sale_detail_dypart table is determined by the region column in the sale_detail table. The region column in the dynamic partition of the sale_detail_dypart table is determined by the sale_date column in the sale_detail table. 
    +------------+-------------+-------------+------------+------------+
    | shop_name  | customer_id | total_price | sale_date  | region     |
    +------------+-------------+-------------+------------+------------+
    | s1         | c1          | 100.1       | china      | 2013       |
    | s2         | c2          | 100.2       | china      | 2013       |
    | s3         | c3          | 100.3       | china      | 2013       |
    +------------+-------------+-------------+------------+------------+
  • 例4: 動的パーティションにデータを挿入する場合、動的パーティションの列をselect_statementで指定する必要があります。 そうでない場合、データの挿入に失敗します。 誤った使用法のサンプルステートメント:

    insert overwrite table sale_detail_dypart partition (sale_date='2013', region)
    select shop_name,customer_id,total_price from sale_detail;
  • 例5: 動的パーティションにデータを挿入するときに低レベルのサブパーティションのみを指定すると、高レベルのパーティションにデータを挿入できない場合があります。 誤った使用法のサンプルステートメント:

    insert overwrite table sale_detail_dypart partition (sale_date, region='china')
    select shop_name,customer_id,total_price,sale_date from sale_detail_dypart;
  • 例6: パーティションキー列のデータ型がselect_statementの列のデータ型と完全に一致しない場合、MaxComputeが動的パーティションにデータを挿入するときに暗黙的な変換が実行されます。 次のステートメントは例を示します。

    -- Create a source table named src. 
    create table src (c int, d string) partitioned by (e int);
    
    -- Add a partition to the src table. 
    alter table src add if not exists partition (e=201312);
    
    -- Append data to the src table. 
    insert into src partition (e=201312) values (1,100.1),(2,100.2),(3,100.3);
    
    -- Create a destination table named parttable. 
    create table parttable(a int, b double) partitioned by (p string);
    
    -- Insert data from the src table into the parttable table. 
    insert into parttable partition (p) select c, d, current_timestamp() from src;
    
    -- Query data in the parttable table. 
    set odps.sql.allow.fullscan=true;
    select * from parttable;
    
    -- The following result is returned: 
    +------------+------------+------------+
    | a          | b          | p          |
    +------------+------------+------------+
    | 1          | 100.1      | 2020-11-25 15:13:28.686 |
    | 2          | 100.2      | 2020-11-25 15:13:28.686 |
    | 3          | 100.3      | 2020-11-25 15:13:28.686 |
    +------------+------------+------------+
    説明

    データが順序付けられている場合、データが動的パーティションに挿入されるときにランダムに分散されます。 これにより、データの圧縮率が低下する。 この場合、Tunnelコマンドを使用してデータを動的パーティションにアップロードし、データ圧縮率を上げることを推奨します。 Tunnelコマンドの使用方法の詳細については、「動的パーティション分割に基づくApsaraDB RDSからMaxComputeへのデータ移行」をご参照ください。