Data skipping with Z-order indexes for Delta Lake | Databricks on AWS [2022/10/28時点]の翻訳です。
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
Deltaテーブルにデータを書き込む際、データスキップに関する情報が自動的に収集されます。DatabricksにおけるDelta Lakeでは、クエリーを高速化するためにクエリー実行時にこの情報(最小値と最大値)を活用します。データスキップの設定を行う必要はありません。利用できる際には常にこの機能は有効化されます。しかし、この効果はデータのレイアウトに依存します。ベストな結果を得るには、Z-orderingを適用します。
DatabricksにおけるDelta Lakeはデフォルトでは、テーブルのスキーマに定義されている最初の32カラムの統計情報を収集します。この値はテーブルプロパティのdelta.dataSkippingNumIndexedCols
で変更することができます。統計情報を収集するカラムを増やすと、ファイルに書き込む際のオーバーヘッドが増加します。
長い文字列から統計情報を収集することは高コストなオペレーションとなります。長い文字列からの統計情報の収集を避けるには、長い文字列を含むカラムを避けるようにテーブルプロパティdelta.dataSkippingNumIndexedCols
を指定するか、ALTER TABLE ALTER COLUMN
を用いて長い文字列のカラムをdelta.dataSkippingNumIndexedCols
より大きい場所に移動します。ALTER TABLEをご覧ください。
統計情報を収集するために、ネストされたカラムのフィールドは個別のカラムとみなされます。
Z-orderingとは?
Z-orderingは、関連する情報を同じファイルセットに配置するテクニックです。この局所性は、自動でDatabricksのDelta Lakeによるデータスキッピングアルゴリズムによって使用されます。この挙動によって、DatabricksのDelta Lakeの読み込むデータ量を劇的に削減します。データをZ-orderするには、ZORDER BY
句で並び替えるカラムを指定します。
OPTIMIZE events
WHERE date >= current_timestamp() - INTERVAL 1 day
ZORDER BY (eventType)
あるカラムが頻繁にクエリー条件に指定され、そのカラムが高いカーディナリティを持っている(すなわち、大量の固有値を持つ)のであればZORDER BY
を使いましょう。
カンマ区切りで複数のカラムをZORDER BY
に指定することができます。しかし、カラムを追加するごとに局所性の効果は失われます。統計情報が収集されていないカラムに対するZ-orderingは効果がなく、リソースの無駄となります。これは、データスキッピングでは、min、max、countのようなカラムローカルの統計情報が必要となるためです。スキーマでカラムを再度並び替える、あるいは統計情報を収集するカラムの数を増やすことで、特定のカラムに対して統計情報を収集するように設定することができます。
注意
-
Z-orderingは冪等性がありませんが、インクリメントなオペレーションで使用することができます。複数回実行してもZ-orderingに要する時間が削減することは保証されません。しかし、Z-orderされたばかりのパーティションに新規データが追加されない場合、そのパーティションを再度Z-orderingしても効果はありません。
-
Z-orderingはタプルの数が均等にバランスされたデータファイルを生成しようとしますが、ディスク上のデータサイズが均等になるとは限りません。これら2つの指標は多くの場合相関しますが、そうではない場合もあり最適化タスクの処理時間に偏りが生じることがあります。
例えば、
ZORDER BY date
を行い、最新のレコードがすべて前回のZORDERのものよりも幅が広い(長い配列や文字列など)場合、OPTIMIZE
ジョブのタスク時間や結果ファイルのサイズに偏りが生じることになります。しかし、これはOPTIMIZE
コマンド自身のみの問題です。以降のクエリーにネガティブなインパクトを起こすことはありません。