Deltaテーブルでのファイルスキップ

ファイルのスキップは Delta Lake の読み取り最適化であり、Spark エンジンは、一致する行を含めることができないデータ ファイルのスキャンを回避できます。 エンジンが読み取るデータが少なくなるため、クエリの実行速度が速くなり、消費される I/O リソースが少なくなります。

ファイルのスキップのしくみ

Delta Lake では、データ ファイルが Delta テーブルに書き込まれるたびに、ファイルごとの列の統計がトランザクション ログに記録されます。 これらの統計には、そのファイル内のインデックス付き列ごとの 最小値最大値および null カウント が含まれます。

クエリにフィルター述語が含まれている場合、エンジンは述語値を各ファイルに格納されている最小/最大範囲と比較します。 述語の値がファイルの範囲外の場合、そのファイルは完全にスキップされます。ファイルを開いたりスキャンしたりする必要はありません。

たとえば、日付範囲によって 5 つのデータ ファイルにパーティション分割された sales テーブルについて考えてみます。

ファイル 最小/最大値 WHERE date = '2024-03-15' の結果
ファイル 1 date [2024-01-01 .. 2024-02-28] スキップ
ファイル 2 date [2024-03-01 .. 2024-03-31] ✓ を読み取る
ファイル 3 date [2024-04-01 .. 2024-05-31] スキップ
ファイル 4 date [2024-06-01 .. 2024-07-31] スキップ
ファイル 5 date [2024-08-01 .. 2024-09-30] スキップ

この場合、最小/最大範囲がフィルター値と重複しないため、5 つのファイルのうち 4 つ (スキャンされるデータが 80% 少なくなります) がスキップされます。

Important

述語値のデータ型は、列の型と一致する必要があります。 型の不一致により、エンジンがスキップにファイル レベルの統計情報を使用できなくなる可能性があります。

既定の動作

Delta Lake では、次の既定値でファイル統計が自動的に収集されます。

  • 統計が収集されるのは、 最初の 32 列 (序数位置別) のみです。
  • ファイルごとの列ごとに追跡される統計: minmaxnull の数
  • 長い文字列列の統計を収集するとコストがかかり、書き込みのオーバーヘッドが増えるため、配置が重要になります。

delta.dataSkippingNumIndexedCols テーブル プロパティは、列の制限を制御します。 そのしきい値を超える列は、ファイル レベルの統計情報を取得せず、ファイルスキップに参加できません。

対象となるデータ型

すべての列の種類でファイル レベルの統計がサポートされているわけではないため、ファイルのスキップが行われます。 エンジンは、各列のデータ型を評価して、最小/最大統計を収集できるかどうかを判断します。

常に対象となる (アトミック型)

  • NumericType (ByteTypeShortTypeIntegerTypeLongTypeFloatTypeDoubleTypeDecimalType)
  • DateType
  • TimestampType
  • TimestampNTZType
  • StringType

条件付きで対象

Note

次の種類は、Fabric Spark ランタイム 2.0 (Delta 4.1) 以降で有効にすることができます。

  • VariantType: spark.databricks.delta.variantShredding.collectVariantDataSkippingStats が有効な場合。
  • ArrayType: spark.microsoft.delta.skipping.complexTypes.enabled が有効で、要素の型自体が対象である場合。
  • MapType: spark.microsoft.delta.skipping.complexTypes.enabled が有効になっており、キーと値の両方の型が対象となる場合。

対象外

  • BinaryType
  • BooleanType
  • StructType (全体として、構造体内のリーフ フィールドは個別に評価されます)
  • NullType

列の網羅率を最大化する

ファイルのスキップの利点を最大限に活用するには、最も頻繁にフィルター処理する列がファイル統計でカバーされていることを確認します。

頻繁にフィルター処理される列を最初に配置する

テーブル スキーマの最初の 32 個の序数位置に、 WHERE 句、結合キー、およびフィルター述語で最も頻繁に表示される列を配置します。 めったに役に立たない統計情報への書き込みオーバーヘッドを無駄にしないよう、長い文字列の列や選択度の低い列は 32 列目より後に配置します。

ALTER TABLE table_name ALTER COLUMN long_str_col AFTER last_indexed_col

インデックス付き列の数を増やす

統計の恩恵を受ける 32 列を超えるテーブルがある場合は、既定の制限を引き上げます。

ALTER TABLE table_name SET TBLPROPERTIES ('delta.dataSkippingNumIndexedCols' = '40')

Note

インデックス付き列の数を増やすと、すべてのデータ ファイルの書き込みオーバーヘッドが増加します。 フィルター述語で余分な列が頻繁に使用される場合にのみ、この値を増やします。

統計の正確な列を指定する

delta.dataSkippingStatsColumnsを使用して、序数の位置に関係なく、ファイル統計を取得する列を明示的に制御します。

ALTER TABLE table_name SET TBLPROPERTIES ('delta.dataSkippingStatsColumns' = 'col1,col2')

delta.dataSkippingStatsColumnsが設定されている場合は、指定された列のみが収集された統計を取得します。 この方法では、書き込みコストと読み取り特典の間のトレードオフをきめ細かく制御できます。

ファイルのスキップとデータ レイアウトの組み合わせ

ファイルのスキップは、関連する値が同じファイルに併置されている場合に最適です。 ZORDER BYや液体クラスタリングなどの手法では、同様の列値を持つ行が同じファイルに格納されるように、データが物理的に再構成されます。 同様の値を併置すると、ファイルあたりの最小/最大範囲が強化され、特定のフィルターに対してエンジンがスキップできるファイルの割合が増加します。

データ レイアウトの最適化の詳細については、 テーブル圧縮Liquid クラスタリングZ オーダーに関するページを参照してください。