Databricks

Databricks Query Optimization Patterns: ファイルサイズ・AQE・Join最適化・Spill対策

2026-03-26
更新: 2026-03-27
NicheeLab編集部

Databricksでのクエリパフォーマンスは「ファイルサイズの適正化」「AQE(Adaptive Query Execution)の活用」「Join戦略の選択」「Spill(ディスク溢出)の回避」の4軸で大きく改善します。 本稿では各軸の設計パターンとパラメータ設定を、Data Engineer Professional試験と実務の両面から整理します。

ファイルサイズ設計

Delta LakeやParquetのファイルサイズは、読み取りパフォーマンスに直結します。 ファイルが小さすぎるとメタデータオーバーヘッドとタスク起動コストが増大し(Small File Problem)、 大きすぎるとパーティション内の並列度が下がります。

パラメータ / 操作目的推奨値
OPTIMIZE小さなファイルを結合して最適サイズに圧縮ターゲットサイズ 128MB(デフォルト 1GB、テーブル特性で調整)
delta.targetFileSizeOPTIMIZEのターゲットファイルサイズ128MB〜256MB(読み取りパターンに応じて調整)
spark.sql.files.maxPartitionBytes読み取り時に1タスクが処理する最大バイト数128MB(デフォルト)
spark.sql.files.openCostInBytesファイルオープンコストの見積もり4MB(デフォルト)
autoOptimize(autoCompact)書き込み後に自動で小ファイルを圧縮ストリーミング書き込みテーブルで有効化推奨
-- OPTIMIZEの実行(ZORDERと組み合わせ可能)
OPTIMIZE gold.orders ZORDER BY (customer_id, order_date);

-- テーブルプロパティでターゲットサイズを設定
ALTER TABLE gold.orders
SET TBLPROPERTIES (
  'delta.targetFileSize' = '134217728'  -- 128MB
);

-- autoOptimizeの有効化
ALTER TABLE silver.events
SET TBLPROPERTIES (
  'delta.autoOptimize.optimizeWrite' = 'true',
  'delta.autoOptimize.autoCompact' = 'true'
);

ZORDER BYはフィルタ条件に頻出するカラムを指定します。 ZORDERはカラム値でデータを空間的にクラスタリングし、Data Skippingの効果を最大化します。 ただし、ZORDERは高カーディナリティのカラム(UUIDなど)には効果が薄いため、3〜4カラム以下に絞ります。

AQE(Adaptive Query Execution)設定パラメータ

AQEは実行時の統計情報に基づいてクエリプランを動的に最適化する機能です。 Databricksではデフォルトで有効であり、以下の3つの最適化を自動的に行います。

  • Coalescing Post-Shuffle Partitions: Shuffleの結果パーティションが小さすぎる場合に結合
  • Converting Sort-Merge Join to Broadcast Hash Join: 実行時にテーブルサイズが十分小さいと判明した場合にBroadcast Joinに切り替え
  • Optimizing Skew Joins: 特定のキーに偏ったパーティション(データスキュー)を分割して並列化
パラメータデフォルト値説明
spark.sql.adaptive.enabledtrueAQE全体の有効/無効
spark.sql.adaptive.coalescePartitions.enabledtrue小パーティション結合の有効/無効
spark.sql.adaptive.coalescePartitions.minPartitionSize1MB結合後のパーティション最小サイズ
spark.sql.adaptive.advisoryPartitionSizeInBytes64MB結合後の推奨パーティションサイズ
spark.sql.adaptive.skewJoin.enabledtrueスキューJoin最適化の有効/無効
spark.sql.adaptive.skewJoin.skewedPartitionFactor5中央値の何倍でスキュー判定するか
spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes256MBスキュー判定の絶対閾値
spark.sql.adaptive.autoBroadcastJoinThreshold30MBAQEがBroadcast Joinに切り替えるサイズ閾値

Join最適化: 戦略の選択基準

SparkのJoin戦略は主に3種類あり、テーブルサイズとデータ特性に応じて選択されます。 AQEが有効な場合は実行時に動的に切り替わりますが、設計段階での理解が重要です。

Join戦略条件メリット注意点
Broadcast Hash Join片方のテーブルがautoBroadcastJoinThreshold以下Shuffleなし。最速大テーブルをBroadcastするとDriverのOOM
Sort-Merge Join両方のテーブルが大きい場合のデフォルト安定。大テーブル同士で確実に動作ソート+Shuffleのコストが高い
Shuffle Hash Join一方がやや大きく、もう一方がメモリに収まる場合Sort不要でSort-Mergeより速い場合があるメモリ消費が大きく、Spillリスク
-- 小テーブルを明示的にBroadcastする(ヒント指定)
SELECT /*+ BROADCAST(dim_products) */
  f.order_id,
  f.amount,
  d.product_name
FROM fact_orders f
JOIN dim_products d ON f.product_id = d.product_id;

-- autoBroadcastJoinThresholdの調整
SET spark.sql.autoBroadcastJoinThreshold = 50m;  -- 50MBまでBroadcast

BROADCASTヒントはオプティマイザの判断を上書きします。 ディメンションテーブル(数万〜数十万行)とファクトテーブル(数億行)のJoinでは、ディメンション側にBROADCASTヒントを指定するのが定石です。

Shuffleパーティション数の設計

spark.sql.shuffle.partitionsはShuffle時のパーティション数を制御します。デフォルトは200ですが、データ量に応じて調整が必要です。

  • データ量が小さい場合(数GB以下): 200は過大。パーティション数を減らすことでタスクオーバーヘッドを削減
  • データ量が大きい場合(数百GB以上): 200では各パーティションが大きすぎてSpillが発生。パーティション数を増やす
  • AQEが有効なら: coalescePartitionsが自動で小パーティションを結合するため、大きめに設定して問題ない
-- Shuffleパーティション数の調整
SET spark.sql.shuffle.partitions = 400;

-- AQE有効時の推奨パーティションサイズ
SET spark.sql.adaptive.advisoryPartitionSizeInBytes = 128m;

Spill(ディスク溢出)対策

SpillはShuffle、Sort、Aggregation時にメモリが不足した場合にデータをディスクに退避する動作です。 パフォーマンスが大幅に劣化するため、Spillの発生を最小化する設計が重要です。

対策方法効果
パーティション数の増加spark.sql.shuffle.partitions を増やす各タスクのデータ量を減らしメモリ内処理に収める
メモリ増強メモリ最適化インスタンスタイプに変更executor当たりのメモリ容量を拡大
Broadcast Joinの活用小テーブル側をBroadcastしてShuffleを回避Shuffle自体を排除
データの事前フィルタリングJOIN前にWHERE句で不要データを除外Shuffle対象データ量を削減
スキュー対策AQEのskewJoinを有効化、またはsaltingテクニック偏ったパーティションを分散
-- Spark UIで確認すべきメトリクス
-- Stages > Task Details:
--   Shuffle Spill (Memory): メモリからディスクに溢れたデータ量
--   Shuffle Spill (Disk):   ディスクに書き込まれたデータ量

-- Spillが発生している場合の対策例
SET spark.sql.shuffle.partitions = 800;    -- パーティション分割を細かく
SET spark.sql.adaptive.advisoryPartitionSizeInBytes = 64m; -- AQE推奨サイズを小さく

Photonエンジンの活用

PhotonはDatabricksのネイティブベクトル化実行エンジンで、Scan、Filter、Aggregation、Joinの各ステージを高速化します。 Photon対応のクラスターを使用するだけで有効になり、特別なSQLの書き換えは不要です。

  • Scan: Parquet/Deltaの列指向読み取りをSIMD命令で高速化
  • Filter/Aggregation: C++ネイティブコードで処理し、JVMのGCオーバーヘッドを排除
  • Join: ハッシュテーブル構築がネイティブコードで高速化
  • 制約: UDFやPython UDFはPhoton対象外。SQL/DataFrameの組み込み関数を使うことでPhotonの恩恵を最大化

最適化チェックリスト

  • テーブルに定期的にOPTIMIZE + ZORDERを実行し、ファイルサイズを128MB前後に維持する
  • ストリーミングテーブルにはautoOptimizeを有効化する
  • AQEはデフォルト有効のまま運用し、advisoryPartitionSizeInBytesをデータ量に応じて調整する
  • ディメンションテーブルとのJoinではBROADCASTヒントを検討する
  • Spark UIのStagesタブでShuffle Spill (Disk)を監視し、Spillが恒常的に発生するクエリは設計を見直す
  • Photon対応クラスターを使用し、可能な限りSQL組み込み関数でロジックを書く

問題で確認

Data Engineer Professional

問題 1

10億行のファクトテーブルと5万行のディメンションテーブルをJoinするクエリが遅い。Spark UIを確認するとSort-Merge Joinが選択され、Shuffle Spill (Disk) が大量に発生している。最も効果的な改善策はどれか。

  1. ディメンションテーブルに対してBROADCASTヒントを指定し、Shuffleを排除する
  2. spark.sql.shuffle.partitions を 10 に減らしてタスク数を削減する
  3. spark.sql.adaptive.enabled を false に設定してAQEを無効化する
  4. ファクトテーブルにOPTIMIZE ZORDERをJoinキー以外のカラムで実行する

正解: A

5万行のディメンションテーブルはBroadcast可能なサイズです。BROADCASTヒントでBroadcast Hash Joinに切り替えると、Shuffleが排除されSpillも解消します。パーティション数を減らすとタスク当たりのデータ量が増えSpillが悪化します。AQE無効化は最適化機能を失います。ZORDERをJoinキー以外で実行してもJoinのShuffle/Spillには影響しません。

よくある質問

OPTIMIZEはどのタイミングで実行すべきですか?

バッチ書き込み完了後、下流のクエリが実行される前が最適です。典型的にはETLジョブの末尾にOPTIMIZEタスクを入れるか、日次のメンテナンスジョブとしてスケジュールします。ストリーミング書き込みのテーブルでは、Databricksの自動最適化(autoOptimize)を有効にすることで手動実行を減らせます。頻繁にOPTIMIZEを実行するとコンピュートコストが増えるため、読み取りパフォーマンスとのバランスで頻度を決めます。

AQEはデフォルトで有効ですか?無効にするケースはありますか?

Databricks Runtime 12.x以降ではAQE(spark.sql.adaptive.enabled)はデフォルトで有効です。AQEを無効にすべきケースは稀ですが、ベンチマーク時にAQEの影響を除外したい場合や、AQEのパーティション結合が特定クエリで逆効果になる場合(検証で確認)に限定的に無効化します。通常の運用では有効のまま推奨です。

Spill(ディスク溢出)が発生しているかどうかはどこで確認できますか?

Spark UIのStagesタブで各タスクのShuffle Spill (Memory) と Shuffle Spill (Disk) を確認できます。Spill (Disk) が0でなければディスクへの溢出が発生しています。また、SQLタブのクエリ実行計画でSortやHashAggregateノードのspill metricsも確認できます。定常的にSpillが発生するクエリでは、spark.sql.shuffle.partitionsの調整やメモリ増強を検討します。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Databricks

Databricks資格一覧|全7試験・難易度・勉強法

Databricks認定資格全7試験の一覧・難易度・出題範囲・合格ラインを徹底解説。2026年最新版の公式試験ガイドに準...

Databricks

Databricks試験の難易度ランキング|全7資格を徹底比較

Databricks認定全7試験の難易度をランキング形式で徹底比較。合格率・学習時間・出題傾向から難易度を分析。...

Databricks

Databricks資格の勉強方法|最短合格ルートと学習時間の目安

Databricks認定資格に最短で合格するための勉強方法を完全ガイド。公式リソース・問題集・学習スケジュールを徹底解説...

Databricks

Databricks Data Engineer Associate完全解説|出題範囲・問題例・合格戦略

Databricks Certified Data Engineer Associate試験を徹底解説。5つの出題ドメイ...

Databricks

Databricks Data Engineer Professional完全解説|上級試験の攻略法

Databricks Certified Data Engineer Professional試験を徹底解説。10の出題...

Databricksの記事一覧 (105件)
© 2026 NicheeLab All rights reserved.