本トピックでは、テーブルに対するデータ操作言語 (DML) 操作の実行に関するよくある質問 (FAQ) に回答します。
|
カテゴリ |
FAQ |
|
データの挿入または更新 |
|
|
データの削除 |
INSERT 操作中にエラーが発生した場合、元のデータは破損しますか
いいえ、元のデータは破損しません。 MaxCompute は原子性を保証します。 INSERT 操作が成功した場合、データは更新されます。 操作が失敗した場合、データはロールバックされます。
INSERT INTO または INSERT OVERWRITE ステートメントの実行時にTable xxx has n columns, but query has m columnsというエラーが報告された場合はどうすればよいですか
INSERT INTO または INSERT OVERWRITE ステートメントを実行してデータを挿入する場合、SELECT 句のフィールドがターゲットテーブルのフィールドと一致していることを確認してください。 フィールドは、数、順序、データ型が一致している必要があります。 MaxCompute は、他のフィールドを NULL またはデフォルト値に設定しながら、テーブルの特定のフィールドにデータを挿入することはサポートしていません。 これを実現するには、SELECT 句で値を NULL に設定します。 例: select 'a', null, col_name from table_name;。
INSERT INTO または INSERT OVERWRITE ステートメントの実行時に「a single instance cannot output data to more than 10000 partitions」というエラーが報告された場合はどうすればよいですか
-
現象
INSERT INTO または INSERT OVERWRITE ステートメントを実行すると、次のエラーが返されます:
FAILED: ODPS-0123031:Partition exception - a single instance cannot output data to more than 10000 partitions -
原因
MaxCompute テーブルには最大 60,000 のパーティションを設定できます。 ただし、1 つのジョブがデータを書き込める出力テーブルのパーティション数は最大 10,000 です。 このエラーは通常、パーティションフィールドが正しく設定されていないために発生します。 たとえば、ID フィールドでテーブルをパーティション分割すると、パーティションが多すぎる可能性があります。
-
解決策
数千の動的パーティションを出力するジョブは大規模と見なされます。 ジョブが 10,000 を超えるパーティションを出力する場合、これはビジネスロジックまたは SQL 構文に問題があることを示している可能性があります。 ロジックと構文が正しいことを確認した場合、パーティションテーブルのパーティションフィールドを変更するか、ビジネスロジックを複数のジョブに分割することで、このエラーを防ぐことができます。
MaxCompute テーブルの動的パーティションにデータを挿入するときに「invalid dynamic partition value」というエラーが報告された場合はどうすればよいですか
-
現象
動的パーティションにデータを挿入すると、次のエラーが返されます:
FAILED: ODPS-0123031:Partition exception - invalid dynamic partition value: province=Shanghai -
原因
このエラーは、動的パーティションに無効な値が使用されたために発生します。 動的パーティショニングは、指定されたフィールドに基づいてパーティションを作成します。 これらのパーティションフィールドの値には、特殊文字や漢字を含めることはできません。
-
解決策
動的パーティションにデータを挿入する場合は、次の点にご注意ください:
-
分散環境で動的パーティションにデータを挿入する場合、単一のプロセスで最大 512 の動的パーティションを出力できます。
-
動的パーティション SQL ステートメントでは、2,000 を超える動的パーティションを生成することはできません。
-
動的に生成されたパーティション値を NULL にすることはできません。
-
ターゲットテーブルに複数のパーティションレベルがある場合、INSERT ステートメントを実行するときに一部のパーティションを静的パーティションとして指定できます。 ただし、静的パーティションは、上位のパーティションである必要があります。
-
MaxCompute テーブルに FLOAT データを挿入するときにエラーが報告された場合はどうすればよいですか
MaxCompute V2.0 がサポートする基本的なデータ型についての詳細は、「データ型バージョン」をご参照ください。 FLOAT データ型には定数定義がありません。 FLOAT データを挿入するには、CAST 関数を使用してデータ型を変換します。 たとえば、cast(5.1 as float) は、文字列 '5.1' を FLOAT 値 5.1 に変換します。
MaxCompute SQL で TINYINT、SMALLINT、INT、FLOAT、VARCHAR、TIMESTAMP、BINARY などの新しいデータ型を使用する場合は、次のいずれかの方法で有効にする必要があります。
-
セッションレベル: SQL ステートメントの前に
set odps.sql.type.system.odps2=true;を追加し、一緒に送信します。 -
プロジェクトレベル: プロジェクトオーナーが
setproject odps.sql.type.system.odps2=true;を実行して、プロジェクトの新しいデータ型を有効にします。
同じデータに対して INSERT SELECT 操作と SELECT 操作の結果が異なるのはなぜですか
-
現象
同じ STRING フィールドで SQL ステートメントを実行すると、小数点以下の桁数が一致しません。 SELECT 操作では小数点以下 2 桁が保持されますが、INSERT SELECT 操作では小数点以下が複数桁表示されます。
-
原因
INSERT SELECT 操作では、STRING フィールドが暗黙的に DECIMAL 型に変換されるとき、ROUND 操作が実行される前に、値はまず DOUBLE 型に変換されます。 DOUBLE 型は不正確であるため、ROUND 操作の結果は小数点以下が複数桁になる場合があります。
-
解決策
明示的な変換を使用してください。
CAST関数を使用して、データを明示的にDECIMAL型に変換します。case when pcm.abc is null then 0 else round(cast(pcm.abc as decimal) ,2) end abc
ターゲットテーブルのフィールドのデータ型が VARCHAR(10) の場合、挿入操作中にデータオーバーフローが発生するとエラーが報告されますか
いいえ。 VARCHAR(10) データ型のフィールドにデータを挿入する場合、データの長さが制限を超えると、データは切り捨てられます。
MaxCompute SQL ステートメントの実行時に「Transaction timeout because cannot acquire exclusive lock」というエラーが報告された場合はどうすればよいですか
-
現象
MaxCompute SQL ステートメントを実行すると、次のエラーが発生します:
Failed to run ddltask - Modify DDL meta encounter exception : ODPS-0121096:MetaStore transaction conflict - Reached maximum retry times because of OTSStorageTxnLockKeyFail(Inner exception: Transaction timeout because cannot acquire exclusive lock.) -
原因
MaxCompute では、複数のジョブが単一のテーブルに同時にデータを書き込むことができます。 複数のジョブが同時にメタデータコミットフェーズに入ると、各ジョブはテーブルのメタデータに対するロックを取得して書き込みを行い、その後にロックを解放する必要があります。 多数のジョブがこれを同時に試行すると、メタデータが長期間ロックされたままになる可能性があります。 これにより、他のジョブがロックの取得を待機している間にタイムアウトし、
cannot acquire exclusive lockエラーが発生する可能性があります。 ジョブは、約 30 秒以内にロックを取得できない場合、タイムアウトします。 ロックの粒度はテーブルレベルです。 -
解決策
同じテーブルまたはテーブルパーティションに対して複数の読み取りおよび書き込み操作が同時に実行されているかどうかを確認してください。 テーブルまたはテーブルパーティションに対して複数の読み取りおよび書き込み操作を同時に実行することは避けてください。
MaxCompute テーブルまたはパーティションのデータを更新するにはどうすればよいですか
MaxCompute は、トランザクションテーブルのデータに対して、update 操作による行レベルの更新をサポートします。
非トランザクションテーブルに対して update 操作を実行すると、 trying to update a non-transactional table is not allowed. Set tblproperties ("transactional" = "true") to use this feature というエラーが報告されます。
ソースパーティションまたはテーブルからターゲットパーティションまたはテーブルにデータをインポートし、インポート中に更新操作を実行できます。 ターゲットをソース自体にすることもでき、これはインプレース更新と呼ばれます。
トランザクションテーブルの作成方法の詳細については、「テーブル操作」をご参照ください。 MaxCompute では、テーブルの作成時にのみ transactional プロパティを設定できます。 既存のテーブルの transactional プロパティを変更するために alter table を使用することはできません。
MaxCompute テーブルまたはパーティションからデータを削除するにはどうすればよいですか
MaxCompute は、トランザクションテーブルのデータに対して、delete 操作による行レベルの削除をサポートします。
非トランザクションテーブルの場合は、次の方法でデータを削除できます。
-
DROPコマンドを実行してテーブル全体を削除します。 -
非パーティション化テーブルの場合、
truncate table table_name;コマンドを実行してテーブルからすべてのデータを削除するか、insert overwriteコマンドを使用して同様の結果を得ることができます。-
例1: TableA から
Col=1のデータを削除します。insert overwrite table TableA select a,b,c.... from TableA where Col <> 1; -
例2: すべてのデータを削除します。
insert overwrite table TableA select a,b,c.... from TableA where 1=2;
-
-
パーティションテーブルの場合、
alter table table_name drop if exists partition(partition_name='specific_partition_value')コマンドを実行して、対応するパーティションを削除します。たとえば、
testtableテーブルのパーティションキー列はdsです。 次のコマンドを実行して、ds='20170520'パーティションを削除します。alter table testtable drop if exists partition (ds='20170520'); -
WHERE 句を指定した INSERT ステートメントを使用して、必要なデータを新しいパーティションまたはテーブルにインポートします。 INSERT ステートメントのソーステーブルとターゲットテーブルは同じにすることができます。
insert overwrite table sale_detail select * from sale_detail where name='tanaka_ichiro';
非パーティション化テーブルに大量のデータが含まれている場合、そこから重複データを削除するにはどうすればよいですか
重複する行のすべての列が同一である場合は、すべての列に対して GROUP BY 操作を実行できます。 たとえば、非パーティション化テーブル table1 に c1、c2、c3 の列がある場合、次のコマンドを実行できます。
insert overwrite table table1 select c1, c2, c3 from table1 group by
c1, c2, c3;
この操作を実行する前に、データをバックアップしてください。 データ量に基づいて、この方法のコストがデータを再インポートするコストよりも低いかどうかを評価してください。