Skip to content

DELETE文の構文

DELETE文は、テーブルから行を削除するために使用します。

DELETE文は、不正なデータ、重複データ、古いデータなど、不要な行を削除するのに役立ちます。

DELETE文は、TrinoとHiveの両方のクエリエンジンでサポートされています。

構文

DELETE FROM <table_name> WHERE <condition>

各項目について:

  • <table_name> は削除対象のテーブル名です
  • <condition> は検索条件を指定する句です

意図しないデータ削除の発生を抑えるため、WHERE句のないDELETE文は許可されていません。

航空便で出荷されたすべての品目を削除する例:

DELETE FROM lineitem WHERE shipmode = 'AIR'

2017年7月1日(UTC)のすべてのイベントログを削除する例:

DELETE FROM lineitem WHERE TD_TIME_RANGE(time, '2017-07-01','2017-07-02')

制限事項

WHERE句のないDELETEは不可

意図しないデータ削除の発生を抑えるため、DELETE文ではWHERE句を含める必要があります。

エラーの例:

Does not support DELETE statement without WHERE condition

Data Tankに対するDELETE

Data Tankに格納されているデータに対してDELETE文を発行することはできません。 Data Tankに格納されたデータに対してDELETE文を発行するには、PostgreSQL Data Tankに直接接続してください。

一度に削除できるパーティション数の上限

1つのDELETEクエリで削除できるパーティション数は最大500kです。 この上限を超えるとDELETEクエリは失敗します。

DELETE文の影響範囲を減らす

上限超過エラーやタイムアウトエラーでDELETEクエリが失敗した場合は、 影響範囲を減らすようにDELETE文を書き換えてください。 最も効果的な方法は、TD_TIME_RANGEまたはTD_INTERVALを使ってDELETEの時間範囲を制限するWHERE句を追加することです。 たとえば、1年分のゲーム履歴データがある場合、次のクエリではなく、

DELETE FROM game_history WHERE player_id=1000;

次のように書き換えます。

DELETE FROM game_history
  WHERE player_id=1000
  AND TD_TIME_RANGE(time, '2018-01-01', '2018-02-01','PDT')

その後、すべての行が削除されるまで、時間範囲を変えながら削除を繰り返します。

DELETE文のタイムアウトエラー

DELETE文の影響範囲が非常に大きい場合、DELETEクエリは数時間かかることがあります。 この場合、クエリがタイムアウトしてジョブが失敗することがあります。 タイムアウトエラーでジョブが失敗した場合は、影響範囲を減らすようにDELETE文を書き換えてください。 DELETE文の影響範囲を減らすを参照してください。

同一テーブルに対する同時DELETE/UPDATE文は競合する可能性があります

同一テーブルに対して複数のDELETE文を同時に実行すると、 実行時間が長くなったり、クエリが失敗したりすることがあります。これは、 内部のパーティションファイル削除処理が競合するためです。一般的なガイドラインとして、 DELETE文の同時実行は避けることをおすすめします。競合の発生可能性は、 DELETE文の条件、データ量、テーブルのデータ分布など、さまざまな要因に依存し、予測が困難です。

競合によりDELETE文が失敗した場合は、クエリを再実行してください。

DELETE文のリソース消費

DELETEクエリはジョブを発行し、リソースを消費します。Treasure Dataで使用されている ストレージおよびインデックス方式の特性上、DELETEクエリはリソースを多く消費する場合があります。

DELETEクエリでフルテーブルスキャンが発生しないようにするには、以下を使用してください:

  • テーブルがデフォルトの時間ベースパーティショニングを使用している場合は、TD_TIME_RANGEやTD_INTERVALなどの時間式
  • テーブルがユーザー定義パーティショニングを使用している場合は、すべてのパーティションキーに対する等価述語

たとえば、テーブルが時間でパーティショニングされていて、2018年6月に作成されたユーザーセットを 削除しようとしている場合、それがDELETE文の重要なパラメーターでなくても、時間制約を含めてください。

たとえば、次のように記述します:

DELETE FROM logtable WHERE userid IN (1234, 1235, 1236) AND TD_TIME_RANGE(time, '2017-06-01','2017-07-01')

時間制約を含めることで、クエリの速度が大幅に向上し、消費するリソースも削減されます。

DELETE文の取り消し

実行済みのDELETE文をロールバックして削除されたデータを復元したい場合は、 Treasure Dataテクニカルサポートに連絡し、実行されたDELETE文を含むジョブのジョブIDを提供する必要があります。 多くの場合、DELETE文を取り消すことができます。ただし、特定の状況ではDELETE文のロールバックができません。

ロールバックができない状況には、次のようなものがあります:

  • 別のDELETE文によって新しいパーティションが削除されている場合。
  • 保持期間の経過により、元のパーティションが破棄されている場合。
  • テーブルが削除され、同じ名前で新しいテーブルが作成されている場合。
  • 内部ストレージのメンテナンス処理の結果として、新しいパーティションがさらに変更または置き換えられている場合。