この記事はDatabricks Advent Calendar 2023の12月14日分として投稿するものです。
削除ベクトルの概要
削除ベクトル(Deletion Vector)はDelta Lakeのストレージ最適化のための新しい技術であり、Delta Lake 2.4以降 (Databricks Runtime 13.2以降)でDeltaテーブルに対して適用可能になっています。
削除ベクトルとは何か?どのように使えばいいかについて解説します。
削除ベクトルの仕組みとメリット
Delta Lakeの更新/削除の際の一般的な挙動
Delta Lakeではデータの更新/削除の際、元ファイルを上書きすることなく、新しいファイルを作成します。つまりParquetファイルから1行でも削除する時は、そのParquetファイルの残りのデータを新しいファイルとして出力することになります。以下のイメージ図の上側の流れになります。
(参照:Delta Transaction Log Protocol | Delta Lake )
削除ベクトルが適用されたDeltaテーブル
一方、削除ベクトルが適用されたDeltaテーブルの場合、新ファイルを作成することなく、削除対象行を表す削除ベクトルファイルが作成されます。以下のイメージ図の下側の流れになります。
削除ベクトルのメリット
- 削除ベクトルを適用することで、削除時にParquetファイルを新規作成する必要がなくなるため、削除が複数のパーティションにまたがり出力するParquetが大量になる場合に短時間で済むというメリットがあります。
- 削除ベクトルが適用されたDeltaテーブルは、DBRが14.2以降でPhotonが有効など一定の条件を満たすと行レベルのコンカレンシーが有効になります。
削除ベクトルの適用
- テーブル作成時だけでなく、既存テーブルに対しても削除ベクトルを適用可能です。
(DBR14.2ではデフォルトで非適用です)
CREATE TABLE <table-name> [options] TBLPROPERTIES ('delta.enableDeletionVectors' = true);
ALTER TABLE <table-name> SET TBLPROPERTIES ('delta.enableDeletionVectors' = true);
- ワークスペースの設定を変更することで、削除ベクトルをデフォルトで有効にすることもできます。詳しくは以下のページを参照ください。
(参考:削除ベクトルの自動有効化 | databricks)
削除ベクトルを使ってみる
実際に、削除ベクトル非適用、削除ベクトル適用のDeltaテーブルを作成して削除するとどう違うのかを試してみました。DBR14.2を使いました。実際のノートブックはgithubに置いてあります。
1 テーブル作成とデータ投入
以下がテーブル作成時のSQLで、SQL最下段のTBLPROPERTIESのところで設定します。上の非適用のテーブルではfalse、下の適用のテーブルではtrueに設定しました。
CREATE OR REPLACE TABLE $catalog_name.$schema_name.$table_dv_false (
date INTEGER NOT NULL,
delay INT NOT NULL,
distance INT NOT NULL,
origin STRING NOT NULL,
destination STRING NOT NULL
)
LOCATION '$external_location_path/$table_dv_false'
TBLPROPERTIES ('delta.enableDeletionVectors' = false);
CREATE OR REPLACE TABLE $catalog_name.$schema_name.$table_dv_true (
date INTEGER NOT NULL,
delay INT NOT NULL,
distance INT NOT NULL,
origin STRING NOT NULL,
destination STRING NOT NULL
)
LOCATION '$external_location_path/$table_dv_true'
TBLPROPERTIES ('delta.enableDeletionVectors' = true);
その後、初期データを投入しました(コードは省略)。
2 削除前のファイル
削除前のファイルの状況をLISTコマンドで見てみると以下の通りです。上が非適用、下が適用のテーブルで、それぞれParquetファイルは1つずつです。
3 データ削除
以下のDELETEコマンドでそれぞれ複数行を削除しました。
DELETE FROM <table name> WHERE origin = 'ATL' AND destination = 'IAD';
4-1 削除ベクトル非適用の場合の削除後のファイル
データ削除後の削除ベクトル非適用のDeltaテーブルのファイルの様子です。このように、旧Parquetファイルはそのままで、それとは別に新しいParquetファイルが出来ています。
4-2 削除ベクトル適用の場合の削除後のファイル
データ削除後の削除ベクトル非適用のDeltaテーブルのファイルの様子です。新Parquetファイルが作られる代わりに、削除ベクトルファイルが作られています。