このトピックでは、MaxCompute のテーブルに対する DML 操作に関してよくある質問への回答を提供します。
カテゴリ | FAQ |
データの挿入または更新 | |
データの削除 |
INSERT 操作中にエラーが発生した場合、元のデータは破損しますか?
いいえ、元のデータは破損しません。MaxCompute はアトミックです。INSERT 操作が成功すると、データが更新されます。INSERT 操作が失敗すると、データはロールバックされます。
Table xxx has n columns, but query has m columns というエラーメッセージが INSERT INTO 文または INSERT OVERWRITE 文の実行時に表示される場合はどうすればよいですか?
INSERT INTO 文または INSERT OVERWRITE 文を実行してデータを挿入する場合、SELECT 文で返される結果のフィールドシーケンス、フィールドタイプ、およびフィールドの総数が、挿入先テーブルのフィールドシーケンス、フィールドタイプ、およびフィールドの総数と一致していることを確認する必要があります。MaxCompute では、INSERT 文でフィールドを指定することはできません。一部の列に NULL 値またはその他のデフォルト値を挿入する場合は、SELECT 文で NULL またはデフォルト値を指定できます。たとえば、INSERT 文で select 'a', null, col_name from table_name; を使用して、最初の 2 つの列に a 値と NULL 値を挿入し、col_name 列の戻り値を 3 番目の列に挿入できます。
「1 つのインスタンスは 10000 を超えるパーティションに出力できません」というエラーメッセージが INSERT INTO 文または INSERT OVERWRITE 文の実行時に表示される場合はどうすればよいですか?
問題の説明
INSERT INTO 文または INSERT OVERWRITE 文を実行すると、次のエラーメッセージが表示されます。
FAILED: ODPS-0123031:Partition exception - a single instance cannot output data to more than 10000 partitions原因
1 つの MaxCompute テーブルには最大 60,000 のパーティションを含めることができます。ただし、1 つのジョブの出力テーブルには最大 10,000 のパーティションしか許可されていません。ほとんどの場合、このエラーはパーティションフィールドの構成が誤っていることが原因です。たとえば、ID フィールドに基づいてパーティション化すると、パーティションが多すぎます。
解決策
ほとんどの場合、ジョブの出力テーブルに何千もの動的パーティションが含まれていると、パーティションの数が多くなります。テーブル内のパーティションの数が 10,000 を超えると、ビジネスロジックまたは SQL 構文でエラーが発生する可能性があります。ロジックエラーまたは構文エラーが発生しない場合は、パーティションテーブルのパーティションフィールドを変更するか、ビジネスロジックを複数のジョブに分割してこのエラーを回避することをお勧めします。
MaxCompute テーブルに動的パーティションを挿入すると、「無効な動的パーティション値」というエラーメッセージが表示される場合はどうすればよいですか?
問題の説明
MaxCompute テーブルに動的パーティションを挿入すると、次のエラーメッセージが表示されます。
FAILED: ODPS-0123031:Partition exception - invalid dynamic partition value: province=上海原因
動的パーティションが無効です。動的パーティション化は、指定されたフィールドに基づいて実行されます。特殊文字または中国語の文字を含むフィールドは、動的パーティションフィールドとして使用できません。
解決策
MaxCompute テーブルに動的パーティションを挿入する前に、次のルールに注意してください。
分散環境で MaxCompute テーブルに動的パーティションを挿入する場合、1 つのプロセスに最大 512 の動的パーティションが存在できます。
動的パーティション化に使用される SQL 文は、2,000 を超える動的パーティションを生成できません。
動的に生成されるパーティション値は NULL にできません。
挿入先テーブルに複数レベルのパーティションが含まれている場合は、INSERT 文で一部のパーティションを静的パーティションとして指定できます。ただし、静的パーティションは高レベルパーティションである必要があります。
FLOAT 型のデータを MaxCompute テーブルに挿入するとエラーが発生する場合はどうすればよいですか?
MaxCompute V2.0 データ型エディションでサポートされている基本データ型の詳細については、「データ型エディション」をご参照ください。FLOAT データ型のデータには定数が含まれていません。この型のデータを挿入するには、まず CAST 関数を使用してデータを FLOAT データ型に変換します。たとえば、cast( 5.1as float) を使用して、STRING 型の '5.1' を FLOAT 型の 5.1 に変換できます。
MaxCompute SQL で TINYINT、SMALLINT、INT、FLOAT、VARCHAR、TIMESTAMP、BINARY などの新しいデータ型を使用する場合は、次のコマンドのいずれかを実行して、セッションまたはプロジェクトに対して MaxCompute V2.0 データ型エディションを有効にする必要があります。
セッション: SQL 文の前に
set odps.sql.type.system.odps2=true;を追加し、コミットして一緒に実行します。プロジェクト: プロジェクトオーナーとして、プロジェクトに対して
setproject odps.sql.type.system.odps2=true;コマンドを実行します。
同じデータに対して INSERT INTO SELECT 文と SELECT 文を実行した後、返される結果が異なります。なぜですか?
問題の説明
STRING 型の同じフィールドに対して INSERT INTO SELECT 文と SELECT 文を個別に実行した後、返される結果の小数点以下桁数が異なります。SELECT 文の結果では、小数点以下 2 桁が保持されます。INSERT INTO SELECT 文の結果では、複数桁の小数点以下が表示されます。
原因
INSERT INTO SELECT 文のフィールドが STRING 型の場合、フィールドが暗黙的に DECIMAL 型に変換されると、最初に DOUBLE 型に変換され、次に ROUND 操作が実行されます。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 文を実行すると、「排他ロックを取得できないためトランザクションがタイムアウトしました」というエラーメッセージが表示される場合はどうすればよいですか?
問題の説明
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 では、複数のジョブで同時に 1 つのテーブルにデータを書き込むことができます。複数のジョブが同時にメタデータをコミットする場合、各ジョブは 1 つのテーブルのメタデータをロック、書き込み、およびロック解除する必要があります。複数のジョブが同時に 1 つのテーブルにデータを書き込む場合、テーブルのメタデータはロック状態のままになります。この場合、一部のジョブはロックを取得する前にタイムアウトする可能性があります。その結果、
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 はテーブルの作成中にのみトランザクションプロパティの設定をサポートしており、ALTER TABLE コマンドを使用して既に作成されたテーブルのこのプロパティを変更することはできません。
MaxCompute テーブルまたはパーティションからデータを削除するにはどうすればよいですか?
MaxCompute では、DELETE 文を実行して、トランザクションテーブルの特定の行からデータを削除できます。
テーブルがトランザクションテーブルでない場合は、次の方法を使用してデータを削除します。
dropコマンドを実行してテーブルを削除します。テーブルがパーティション化されていないテーブルの場合、
truncate table table_name;コマンドを実行してテーブルからデータを削除するか、insert overwriteコマンドを実行して同様の操作を実行できます。例 1: Col の値が 1 であるデータレコードを TableA から削除します。コマンド例:
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 key column='Specific partition value')コマンドを実行してパーティションを削除できます。たとえば、testtable テーブルのパーティションキー列が ds の場合、次のコマンドを実行して
ds='20170520'パーティションを削除します。alter table testtable drop if exists partition (ds='20170520');INSERT 文と WHERE 句を実行して、必要なデータを新しいパーティションまたはテーブルにインポートします。INSERT 文を実行する場合、ソーステーブルと挿入先テーブルは同じにすることができます。
insert overwrite table sale_detail select * from sale_detail where name='mengyonghui';
パーティション化されていないテーブルに大量のデータが含まれている場合、テーブルから重複データを削除するにはどうすればよいですか?
パーティション化されていないテーブルの各列に重複データが含まれている場合は、すべての列に対して GROUP BY 操作を実行できます。たとえば、パーティション化されていないテーブル table1 の列が c1、c2、c3 の場合。次のコマンドを実行して、テーブルから重複データを削除できます。
insert overwrite table table1 select c1, c2, c3 from table1 group by
c1, c2, c3;この操作を実行する前に、データをバックアップし、この操作のコストがデータインポートのコストよりも低いかどうかをデータ量に基づいて評価することをお勧めします。