ファイル システムやリレーショナル データベースと同様に、密接に管理されていない限り、データは時間の経過と同時に断片化され、データを読み取るために過剰なコンピューティング コストが発生します。 Delta Lake は例外ではありません。 個々のファイル操作コストを削減し、データ圧縮を改善し、リーダーの並列処理を最適化するには、データ ファイルを定期的に最適なレイアウトに書き換える必要があります。
OPTIMIZE コマンドは、この課題に対処します。パーティション内の小さなファイルを、理想的なファイル サイズをターゲットとするビンにグループ化し、ストレージに書き換えます。 結果として、同じデータが圧縮されてファイル数が少なくなります。
ヒント
さまざまな消費シナリオ (SQL Analytics エンドポイント、Power BI Direct Lake、Spark) の圧縮戦略に関する包括的なワークロード間ガイダンスについては、 ワークロード間のテーブルのメンテナンスと最適化に関するページを参照してください。
圧縮方法
Microsoft Fabric には、Delta テーブルで最適なファイル サイズを維持するためのいくつかの方法が用意されています。
OPTIMIZE コマンド
OPTIMIZE コマンドは、Delta テーブルを圧縮するための基本的な操作です。 デルタ テーブルのデータ レイアウトを向上させるために、小さなファイルを大きなファイルに書き換えます。
| プロパティ | Description | 既定値 | セッション構成 |
|---|---|---|---|
| minFileSize | このしきい値より小さいファイルはグループ化され、大きなファイルとして書き換えられます。 | 1073741824 (1 g) | spark.databricks.delta.optimize.minFileSize |
| maxFileSize |
OPTIMIZE コマンドによって生成されるターゲット ファイル サイズ。 |
1073741824 (1g) | spark.databricks.delta.optimize.maxFileSize |
Important
OPTIMIZEはべき等操作ですが (つまり、1 行に 2 回実行してもデータは書き換えられません)、Delta テーブル サイズに対して大きすぎるminFileSizeを使用すると、書き込み増幅が発生し、演算の計算コストが必要以上に高くなる可能性があります。 たとえば、 minFileSize が 1 GB に設定されていて、テーブルに 900 MB のファイルがある場合、テーブルに小さな 1 KB のファイルを書き込んで OPTIMIZE を実行すると、妥当なサイズの 900 MB のファイルが書き換えられます。 ファイル サイズを自動的に管理する方法のガイダンスについては、 アダプティブ ターゲット ファイル サイズ のドキュメントを参照してください。
OPTIMIZE Z オーダー付き
ZORDER BY句を指定すると、OPTIMIZEは、z オーダー列の値が似ている行が同じファイルに併置されるように、すべてのアクティブ なファイルを書き換え、それらの列をフィルター処理するクエリに対するファイル スキップの有効性が向上します。 Z オーダーは次の場合に使用します。
- クエリでは、多くの場合、2 つ以上の列 (日付 + customer_idなど) をフィルター処理します。
- これらの述語は十分に選択的であるため、ファイル レベルのスキップがスキャンされるファイルの数を減少させます。
OPTIMIZE dbo.table_name ZORDER BY (column1, column2)
OPTIMIZE V-オーダー付き
VORDER句を指定すると、圧縮対象のファイルに V オーダー最適化が適用されます。 V オーダーの詳細については、詳細な ドキュメントを参照してください。
OPTIMIZE dbo.table_name VORDER
OPTIMIZE 液体クラスタリングを搭載
液体クラスタリングはテーブルオプションとして指定されています。詳細については、 液体クラスタリングの有効化 を参照してください。 液体クラスタリングが有効になっている場合、 OPTIMIZE はクラスタリング ポリシーを適用する物理書き換えを実行します。
Important
データは、 OPTIMIZE が液体クラスター化対応テーブルで実行されている場合にのみクラスター化されます。 通常の書き込み操作では、データはクラスター化されません。 自動圧縮の使用や最適化ジョブの手動スケジューリングなどの圧縮戦略を使用することは、クラスター化されたデータの利点 (つまり、デルタ ファイルのスキップの改善) を実現するために不可欠です。
高速最適化
高速最適化では、Delta テーブル ファイルをインテリジェントに分析し、パフォーマンスを有意に向上させる可能性が高くない圧縮操作をスキップします。
小さなファイルが存在するたびにファイルを盲目的に圧縮する代わりに、高速最適化では、各候補ビン (小さなファイルのグループ) が構成可能なベスト プラクティスの圧縮目標を満たしているかどうかを評価します。 高速最適化では、マージがターゲットの最小サイズに達する可能性がある場合、または小さなファイルが多すぎる場合にのみ、ファイルのビンに圧縮が実行されます。 それ以外の場合は、そのグループをスキップするか、圧縮するファイルの数を減らします。
高速最適化は、圧縮の期待に基づいて微調整できます。
| プロパティ | Description | 既定値 | セッション構成 |
|---|---|---|---|
| minNumFiles | 最適化されたファイルを生成するのに十分なデータがビンに含まれていない場合に、最適化を実行するためにビンに存在する必要がある小さなファイルの数。 | 50 | spark.microsoft.delta.optimize.fast.minNumFiles |
| parquetCoefficient | 最適化コンテキストの最小ファイル サイズを乗算して、圧縮のスコープに含めるビンに存在する必要がある小さなファイル データの最小量を決定します。 | 1.3 | spark.microsoft.delta.optimize.fast.parquetCoefficient |
注
parquetCoefficientにより、ビンのターゲット サイズが最適化コンテキストの最小ターゲット ファイル サイズよりも大きくなります。 この係数は、複数の小さな Parquet ファイルを組み合わせると圧縮が向上し、小さなファイルの合計よりもデータが少なくなるという現実を考慮しています。 この値を増やして、高速最適化でビンをスキップする頻度をより控えめにしたり、小さくしてビンのスキップを制限したりすることができます。
動作方法
高速最適化では、ビンを圧縮する前に追加のチェックが行われます。 候補のビンごとに、高速最適化によって次の結果が評価されます。
- ビン内の生データの推定量 (小さなファイル サイズの合計)
- 小さいファイルを組み合わせて、構成された最小ターゲット サイズを満たすファイルを生成するかどうか
- ビンに構成済みの最小数以上の小さいファイルが含まれているかどうか
高速最適化では、小さなファイルの各ビンが評価され、最小ターゲット サイズに達する可能性がある小さなファイルまたは最小ファイル数を超える可能性がある小さなファイルのみが圧縮されます。 これらのしきい値を満たしていないビンはスキップされるか、部分的に圧縮されます。 最適でないバケットをスキップすると、不要な書き換えが減り、書き込み負荷の増加を抑え、OPTIMIZE ジョブがより安定したものになります。
注
正確な実装は、時間の経過と同時に進化する可能性があります。
高速最適化を行うと、Delta テーブルのライフサイクルにわたって書き換えられるデータが少なくなる可能性があります。 次の図に示すように、高速化最適化では、サブオプティマルなビンの圧縮がスキップされます。結果として、より高速でべき等性のある OPTIMIZE ジョブになり、書き込み増幅の削減が実現します。
注
図の目的上の図では、圧縮から書き込まれたファイルのサイズが小さいファイルのサイズの合計であると想定しています。 それはまた、1 の parquetCoefficient を意味します。
制限事項
- 液体クラスタリングおよび Z オーダー操作には適用されません
- 高速最適化では、自動圧縮の動作は変更されません
ファイル レベルの圧縮ターゲット
圧縮最小サイズターゲットと最大ファイル サイズ ターゲットの変更に基づいて、以前に圧縮 (十分な大きさ) と見なされていたデータの書き換えを回避するために、 spark.microsoft.delta.optimize.fileLevelTarget.enabled を有効にして、既に圧縮されたファイルの再コンパイルを防ぐことができます。 有効にすると、ファイルは圧縮時にターゲット ファイル サイズの少なくとも半分に達していた場合、再圧縮されません。 ファイル レベルのターゲットを維持すると、圧縮ターゲット サイズが時間の経過と同時に変化する (たとえば、アダプティブ ターゲット ファイル サイズの評価とより大きなターゲットの設定から) ため、書き込み増幅が最小限に抑えられます。 有効にすると、OPTIMIZE の実行時に OPTIMIZE_TARGET_SIZE タグが新しいファイルに追加されます。または、 delta.targetFileSize または delta.targetFileSize.adaptive テーブル プロパティが設定されている場合は、書き込み操作に対して追加されます。
注
既定では有効になっていませんが、ファイル レベルの圧縮ターゲット を有効にして、書き込み増幅の可能性を制限することをお勧めします。
自動圧縮
自動圧縮では、書き込み操作のたびにパーティションの正常性が評価されます。 パーティション内の過剰なファイル断片化 (小さなファイルが多すぎる) を検出すると、書き込みがコミットされた直後に同期 OPTIMIZE 操作がトリガーされます。 圧縮はプログラムによって有益であると判断された場合にのみ実行されるため、ファイルのメンテナンスに対するこのライター駆動型のアプローチが最適です。
新しいテーブルで自動圧縮を有効にするには、セッション レベルで設定します。
テーブル レベルで、選択テーブルに対してのみ有効にするように設定します。
CREATE TABLE dbo.table_name
TBLPROPERTIES ('delta.autoOptimize.autoCompact' = 'true')
DataFrameWriter オプションを使用して、新しいテーブルで有効にします。
df.write.option('delta.autoOptimize.autoCompact', 'true').saveAsTable('dbo.table_name')
既存のテーブルで有効にする:
ALTER TABLE dbo.table_name
SET TBLPROPERTIES ('delta.autoOptimize.autoCompact' = 'true')
自動圧縮の動作は、次の Spark セッション構成を使用して調整できます。
| プロパティ | Description | 既定値 | セッション構成 |
|---|---|---|---|
| maxFileSize | 圧縮されたファイルのターゲットの最大ファイル サイズ (バイト単位)。 | 134217728b (128 MB) | spark.databricks.delta.autoCompact.maxFileSize |
| minFileSize | 圧縮と見なされるファイルの最小ファイル サイズ (バイト単位)。 このしきい値を下回る値は圧縮のために考慮され、 minNumFiles しきい値にカウントされます。 |
デフォルトで設定されていない場合、明示的に値を設定しない限り、maxFileSizeの 1/2 として計算されます。 |
spark.databricks.delta.autoCompact.minFileSize |
| minNumFiles | 自動圧縮をトリガーするために、 minFileSize しきい値の下に存在する必要があるファイルの最小数。 |
50 | spark.databricks.delta.autoCompact.minNumFiles |
注
Microsoft では、 ジョブをスケジュールする代わりにOPTIMIZEを使用することをお勧めします。 自動圧縮は一般に、読み取り/書き込みパフォーマンスを最大化する際にスケジュールされた圧縮ジョブよりも優れています。多くの場合、スケジュールされたジョブを実行する頻度のコーディング、スケジュール設定、および最適化のメンテナンス オーバーヘッドを排除します。 自動圧縮は、データ処理サービス レベルの目標が、圧縮が必要な場合にトリガーされる自動圧縮からの待機時間の増加を許容する場合に推奨されます。 データ待機時間の要件が厳しい場合は、同期圧縮操作がトリガーされるため、書き込み操作で定期的なスパイクが発生しないように、別の Spark プールで実行するように最適化をスケジュールする方が効果的な場合があります。
Important
圧縮は採用する重要な戦略ですが、書き込みの最適化などの機能を使用して 小さなファイルを書き込むのを避けること と適切に組み合わせておく必要があります。 詳細については、 書き込みの最適化に関するガイダンスを参照してください。
レイクハウス テーブルのメンテナンス
ユーザーは、Lakehouse UI から OPTIMIZE などのアドホック メンテナンス操作を実行できます。 詳細については、 レイクハウステーブルのメンテナンスを参照してください。
ベスト プラクティスの概要
- 手動スケジュールを回避し、ファイルを自動的に圧縮し続けるために、頻繁に小さな書き込み (ストリーミングまたはマイクロバッチ) を使用するインジェスト パイプラインに対して自動圧縮を有効にします。
- 他の書き込みパターンでは、小さなファイルの蓄積に対する保険として有効にすることが有益な場合がありますが、データ処理サービス レベルの目標が処理時間の定期的な急増を許容するかどうかを検討します。
- 多数のパーティションを書き換えたり、Z オーダーを実行したりする必要がある場合は、
OPTIMIZEの操作をスケジュールします。 -
高速最適化を有効にして書き込みアンプリフィケーションを減らし、
OPTIMIZEのべき等性を高めます。 - テーブルが大きく成長し、ターゲットファイルサイズが大きくなることで発生する書き込み増幅を防ぐため、ファイルレベルの圧縮ターゲットを有効にしてください。
- 書き込み前圧縮 (書き込みの最適化) は、書き込み後の圧縮 (最適化) よりもコストが低くなることに注意してください。 ベスト プラクティスについては、 書き込みの最適化 に関するドキュメントを参照してください。