テーマ切替
Professional 学習教材 ② コスト・パフォーマンス最適化(配点 13%)
Databricks 認定データエンジニア Professional(上位資格)試験のドメイン②「コスト・パフォーマンス最適化」の自習教材です。Associate よりも一段深く、最適化手法の「選択」「トレードオフ」「コスト設計」まで踏み込みます。本教材だけで学習が完結するよう、公式ドキュメント(日本語)を実読して用語・概念・数値しきい値・DBR(Databricks Runtime)バージョン境界を網羅しています。
参照した公式ページ(すべて実読):
- Azure Databricks の最適化に関する推奨事項: https://learn.microsoft.com/ja-jp/azure/databricks/optimizations/
- データファイルレイアウトを最適化する(OPTIMIZE): https://learn.microsoft.com/ja-jp/azure/databricks/tables/operations/optimize
- テーブルに液体クラスタリングを使用する: https://learn.microsoft.com/ja-jp/azure/databricks/tables/clustering
- Databricks のコスト最適化(原則): https://learn.microsoft.com/ja-jp/azure/databricks/lakehouse-architecture/cost-optimization/
- コスト最適化のためのベストプラクティス: https://learn.microsoft.com/ja-jp/azure/databricks/lakehouse-architecture/cost-optimization/best-practices
- パフォーマンス効率のベストプラクティス: https://learn.microsoft.com/ja-jp/azure/databricks/lakehouse-architecture/performance-efficiency/best-practices
- Unity Catalog 管理テーブルの予測最適化: https://learn.microsoft.com/ja-jp/azure/databricks/optimizations/predictive-optimization
- VACUUM を使用して未使用のデータファイルを削除する: https://learn.microsoft.com/ja-jp/azure/databricks/tables/operations/vacuum
- アダプティブクエリ実行(AQE): https://learn.microsoft.com/ja-jp/azure/databricks/optimizations/aqe
- データファイルのサイズを制御する: https://learn.microsoft.com/ja-jp/azure/databricks/tables/tune-file-size
- Spark UI を使用してコストとパフォーマンスの問題を診断する / スキューとスピル: https://learn.microsoft.com/ja-jp/azure/databricks/optimizations/spark-ui-guide/
1. このドメインの概要
このドメインは、Lakehouse のワークロードを「速く」かつ「安く」動かすための設計・診断・自動化を問います。Professional 試験では、単に「OPTIMIZE を実行する」ではなく、どの手法を、どのテーブル特性のときに、どのトレードオフを承知で選ぶかが問われます。
学習の骨格は次の 4 層です。
- データレイアウト最適化(ストレージ側): OPTIMIZE(ビンパッキング)、Z-ORDER、液体クラスタリング(Liquid Clustering)、パーティション設計、ファイルサイズ調整、VACUUM。「小さなファイル問題(small files problem)」の解消とデータスキップ(data skipping)の効率化が中心。
- 自動最適化(運用の自動化): 予測的最適化(Predictive Optimization)、自動圧縮(Auto Compaction)、最適化された書き込み(Optimized Writes)、自動液体クラスタリング(Automatic Liquid Clustering)。手動メンテナンスを排除する方向。
- Spark クエリ実行の最適化(コンピュート側): シャッフル(shuffle)、データスキュー(data skew)、スピル(spill)、AQE(Adaptive Query Execution)、Photon、各種キャッシュ、ブロードキャスト結合(broadcast join)、CBO(Cost-Based Optimizer)。
- コスト最適化(お金の設計): DBU(Databricks Unit)、コンピュートの種類選択(ジョブ/SQL ウェアハウス/サーバーレス)、自動スケーリング(autoscaling)、自動終了(auto termination)、スポットインスタンス、タグ付けによるコスト配分(cost allocation)、予算とシステムテーブルによる監視。
最重要の前提: Databricks のほとんどの最適化は Delta Lake を前提とし、Databricks Runtime 10.4 LTS 以降で既定で有効です。最新の性能を得るには最新の DBR を使うのが基本方針。そして Databricks は近年、**「新しいテーブルはパーティションや Z-ORDER ではなく液体クラスタリングを使い、Unity Catalog マネージドテーブル + 予測的最適化に任せる」**方向を一貫して推奨しています。この「推奨の方向性」を理解しているかが Professional では頻出です。
2. 重要用語集
| 用語(日本語) | English | 説明 |
|---|---|---|
| OPTIMIZE | OPTIMIZE | 小さなファイルを書き換えてデータレイアウトを改善するコマンド。Delta と Apache Iceberg 両対応。液体クラスタリング有効時はキーでグループ化、パーティション定義時はパーティション内で圧縮。 |
| ビンパッキング | Bin-packing | OPTIMIZE の中核処理。小さなファイルをサイズ的に均等なファイルへ結合する。**べき等(idempotent)**で、ファイルあたりのタプル数ではなくストレージ上のサイズで均衡を目指す。 |
| 小さなファイル問題 | Small files problem | 多数の小さなファイルがメタデータ処理と I/O を非効率化し、クエリを遅くする問題。圧縮(compaction)で解消。 |
| Z-ORDER | Z-ORDER (ZORDER BY) | 液体クラスタリングを使わない Delta テーブルで、複数列の値を空間充填曲線で同一ファイルに寄せデータスキップを効かせる手法。OPTIMIZE の書き換え時に適用。Iceberg では非対応(別のクラスタリング/並べ替え戦略)。 |
| 液体クラスタリング | Liquid Clustering | パーティション分割と Z-ORDER を置き換えるデータレイアウト手法。既存データを書き換えずにクラスタリングキーを再定義できる。CLUSTER BY で指定。Delta は DBR 15.4 LTS 以降で GA。 |
| 自動液体クラスタリング | Automatic Liquid Clustering | CLUSTER BY AUTO。クエリ履歴を分析して最適なクラスタリングキーを自動選択・進化させる。UC マネージドテーブル + 予測的最適化が必要。 |
| クラスタリングキー | Clustering key | 液体クラスタリングでデータを整理する基準列。最大 4 列。統計が収集されている列(既定で先頭 32 列)である必要がある。 |
| 予測的最適化 | Predictive Optimization | UC マネージドテーブルに対し OPTIMIZE / VACUUM / ANALYZE を自動実行する機能。サーバーレスコンピュートで非同期実行。 |
| VACUUM | VACUUM | 保持しきい値より古く、参照されなくなったデータファイルを物理削除する。既定保持 7 日。ストレージコスト削減とコンプライアンス(削除レコードの完全消去)に必須。 |
| 保持期間 | Retention duration | VACUUM が保持するファイルの期間。delta.deletedFileRetentionDuration(既定 7 日)。7 日以上を強く推奨。 |
| データスキュー | Data skew | 特定キーにデータが偏り、一部タスクだけ極端に長時間化する現象。クラスター使用率を下げジョブを長引かせる。 |
| シャッフル | Shuffle | 結合・集計などでノード間をネットワーク越しにデータ再配置する処理。分散処理のオーバーヘッドの主因。 |
| スピル | Spill | メモリ不足時にデータをメモリからディスクへ退避する処理。非常にコストが高く、シャッフル中に最も発生しやすい。 |
| パーティション | Partition | (テーブル)ファイルシステム階層でデータを物理分割する静的手法。(Spark)処理単位のデータ分割。テーブルのパーティションは変更が難しく、過剰分割で性能劣化。 |
| ディスクキャッシュ | Disk cache | 旧称 Delta キャッシュ。VM のローカル SSD にリモートデータのコピーを保持し、Parquet の反復読み取りを高速化。ファイル変更を自動検知。 |
| クエリ結果キャッシュ | Query result cache | SQL ウェアハウスでの決定論的クエリの結果をクラスター単位でキャッシュ。NOW() 等の非決定論的述語を避けると効く。 |
| Spark キャッシュ | Spark cache | .persist() / .unpersist()。サブクエリ結果や非 Parquet 形式を保持できるが、誤用でメモリを食い遅くする。原則として避ける。 |
| ブロードキャスト結合 | Broadcast (hash) join | 小さいテーブルを全 Executor に配布し、シャッフルを避ける結合。AQE が実行時に動的採用(既定 30MB しきい値)。 |
| AQE | Adaptive Query Execution | 実行時の実測統計に基づきクエリを再最適化する仕組み(Spark 3.0)。既定で有効。 |
| Photon | Photon | Databricks ネイティブのベクトル化クエリエンジン。Spark API 互換でコード変更不要。SQL ウェアハウスでは既定で有効。 |
| サーバーレス | Serverless | コンピュート層を Databricks が管理するフルマネージド方式。起動が数秒、自動スケール、従量課金。SQL ウェアハウス/ジョブ/ノートブック/モデルサービングで提供。 |
| DBU | Databricks Unit | Databricks の処理能力の課金単位。総コスト = DBU + VM + ディスク + ネットワーク(サーバーレスは DBU に VM 込み)。 |
| コスト配分 | Cost allocation | ワークスペース/クラスター/SQL ウェアハウス/プールへのタグ付けで、コストをチーム・プロジェクトに帰属させる(チャージバック)。 |
| 自動スケーリング | Autoscaling | 負荷に応じワーカーを動的に増減。静的サイズより総コスト削減。ストリーミングは縮小に制限あり。 |
| 自動終了 | Auto termination | 指定アイドル時間後にコンピュートを自動停止。対話型クラスターに設定してコスト削減。 |
| スポットインスタンス | Spot instance | クラウドの余剰 VM を安価に利用。中断リスクあり。ドライバー(最初のインスタンス)は常にオンデマンド推奨。 |
| CBO | Cost-Based Optimizer | テーブル統計(ANALYZE TABLEで収集)を用い、結合種別・ビルド側・結合順序を最適化するオプティマイザ。 |
| コンピュート最適化 | Compute-optimized | CPU 集約ワークロード向けインスタンス。OPTIMIZE / VACUUM 等のメンテナンスやストリーミング向け。 |
| メモリ最適化 | Memory-optimized | シャッフル/スピルが多い ML 等のワークロード向けインスタンス。 |
| ストレージ最適化 | Storage-optimized | キャッシュの恩恵が大きいアドホック/対話型分析向け(ローカル SSD)。 |
| 動的ファイルプルーニング | Dynamic File Pruning (DFP) | クエリ述語に一致しないファイル/ディレクトリをスキップし読み取りを削減。 |
| データスキップ | Data skipping | 各ファイルの min/max 統計でクエリ条件に合わないデータを読み飛ばす。既定で先頭 32 列の統計を収集。 |
| 最適化された書き込み | Optimized Writes | 書き込み前にデータをシャッフルしてファイルサイズを整える。パーティションテーブルで特に有効(既定 128MB)。 |
| 自動圧縮 | Auto Compaction | 書き込み成功後、同期的に小さなファイルを結合(既定 128MB、未圧縮ファイルのみ)。 |
3. 詳細解説
3-1. 最適化の全体像(データレイアウト・診断・自動最適化)
Databricks Runtime に内蔵される自動最適化
Databricks のパフォーマンス強化の多くは自動で、DBR 10.4 LTS 以降で既定有効です。代表:
- ディスクキャッシュ(disk cache): コンピュートに接続されたディスクボリューム(SSD)に Parquet データを読み込み、反復読み取りを高速化。
- 動的ファイルプルーニング(dynamic file pruning): クエリ述語に一致するデータを含まないディレクトリをスキップ。
- 低シャッフルマージ(low shuffle merge):
MERGEが書き換えるデータファイル数を減らし、マージ後のOPTIMIZE再実行の必要を減らす。 - アダプティブクエリ実行(AQE): Spark 3.0 で導入。実行時の再最適化(3-3 で詳述)。
Databricks が推奨する強化(オプトインで効くもの)
- クローン(clone): ソースデータセットの深いコピー(deep clone)/浅いコピー(shallow clone)を作成。
- コストベースオプティマイザ(CBO): テーブル統計を利用してクエリ性能を改善。
- JSON 文字列操作 / 上位の関数(higher-order functions) / 複合データ型(complex types): UDF より高速な組み込み最適化。上位の関数は UDF より性能が良い。
- 範囲結合の最適化(range join optimization): 区間の重なり条件での結合。桁違いの高速化が可能だが手動チューニングが必要。
オプトインの動作(トレードオフに注意)
- 分離レベル(isolation level): 既定は「書き込みシリアル化可能(write serializable)」。「シリアル化可能(serializable)」に変更すると読み取りシリアル化が保証される代わりに、同時実行操作のスループットが低下しうる。
- Bloom フィルターインデックス(Bloom filter index)は非推奨。代わりに予測 I/O(predictive I/O)または液体クラスタリングを使う。
診断は Spark UI から(3-3 と連動)
コスト・パフォーマンス問題の診断は Spark UI で行います。標準的な順序:
- ジョブタイムラインで主要な問題を特定
- 最長ステージを見る
- スキューまたはスピルを探す
- 最長ステージが I/O 依存か判断
- その他の低速要因を探す
3-2. OPTIMIZE・Z-ORDER・液体クラスタリング・予測的最適化・VACUUM
OPTIMIZE(ビンパッキング)
OPTIMIZE はデータファイルを書き換えてレイアウトを改善します(Delta と Iceberg 両対応)。
- 液体クラスタリング有効時: クラスタリングキーでデータをグループ化して書き換え。
- パーティション定義時: ファイル圧縮とレイアウトはパーティション内で実行。
- ビンパッキングは「べき等」: 同じデータセットに 2 回実行しても 2 回目は効果なし。サイズ的に均等なファイルを目指す(ファイルあたりのタプル数と必ずしも一致しないが相関することが多い)。
- 読み取りへの影響なし: 読み手はスナップショット分離(snapshot isolation)を使うため中断されない。OPTIMIZE はデータを変更しないので前後で結果は同じ。ストリーミングソースにも影響しない。
- 戻り値: 削除/追加ファイルの統計(min, max, 合計など)、Z オーダー統計、バッチ数、最適化されたパーティション。
- 実行頻度のトレードオフ: 高頻度 = 高性能・高コスト、低頻度 = 低コスト。まず毎日実行し、その後コスト/性能のバランスで調整するのが推奨。UC マネージドテーブルは予測的最適化に任せるのが最善。
- 推奨インスタンス: 大量の Parquet デコード/エンコードで CPU 集約 → コンピュート最適化インスタンス。接続 SSD の恩恵もある。
- DBR 16.0 以降:
OPTIMIZE FULLで液体クラスタリングの再クラスタリングを強制。
Z-ORDER
液体クラスタリングのない Delta テーブルで、OPTIMIZE ... ZORDER BY (cols) によりデータクラスタリングを改善できます。Iceberg では ZORDER の代わりにクラスタリング/並べ替え戦略が使われます。ただし Databricks は、パーティション・Z-ORDER・その他のレイアウト手法ではなく液体クラスタリングを推奨しています。
液体クラスタリング(Liquid Clustering)— 最重要トピック
位置づけ: パーティション分割と ZORDER を置き換えるデータレイアウト手法。従来のパーティションと異なり、既存データを書き換えずにクラスタリングキーを再定義できる(分析ニーズの変化に追随)。ストリーミングテーブルと具体化ビュー(materialized view)にも適用可能。
GA / バージョン境界:
- Delta テーブル: DBR 15.4 LTS 以降で GA。
- Iceberg テーブル: DBR 16.4 LTS 以降でパブリックプレビュー。
- マネージド Iceberg v3(削除ベクトル・行追跡・行レベル同時実行・自動液体クラスタリング): DBR 18.0 以降。
- クラスタリングのトリガー(
OPTIMIZE): DBR 13.3 LTS 以降。大きなテーブルの OPTIMIZE 性能向上には DBR 17.3 LTS 以降推奨。 - 読み取り: DBR 13.3 LTS 以降(チェックポイント V2 対応)。液体クラスタリングは Delta ライター v7 / リーダー v3 を使用(プロトコルのダウングレード不可)。
液体クラスタリングが特に効くテーブル:
- カーディナリティの高い列でフィルターするクエリ
- データの偏り(スキュー)が大きいテーブル
- 急成長し、メンテ・チューニングが必要なテーブル
- 同時書き込み要件のあるテーブル
- アクセスパターンが多様/変化するテーブル
- 典型的なパーティションキーだとパーティションが多すぎ/少なすぎになるテーブル
クラスタリングキーの選択(試験頻出の数値):
- 最大 4 個まで指定可能。任意の順序で定義できる。
- 高相関の 2 列は片方だけをキーにする。
- 小さいテーブル(10 TB 未満)ではキーを多くすると単一列フィルターの性能が落ちる(例: 4 キーは 2 キーより遅い)。テーブルが大きくなると単一列クエリでの差はごくわずか。
- キーは統計が収集された列である必要がある(既定で先頭 32 列)。
- サポートデータ型: Date, Timestamp, TimestampNTZ(DBR 14.3 LTS 以降), String, Integer/Long/Short/Byte, Float/Double/Decimal。構造体フィールド(ドット表記、任意の深さのネスト)も可。複合型(StructType/MapType/ArrayType)そのものや配列/マップ要素はキーにできない。
有効化の要点:
- パーティションや
ZORDERとは互換性がない(併用不可)。 - 作成時:
CLUSTER BY (cols)。DataFrame/DeltaTable API は DBR 14.3 LTS 以降、DataFrameWriterV2 は DBR 14.2 以降。 - DataFrame API でキーを設定できるのはテーブル作成時か
overwrite(CREATE OR REPLACE TABLE)時のみ。append時はキーを変更できない → データ追加中に変えるなら SQLALTER TABLE ... CLUSTER BY。 - 既存の非パーティションテーブル:
ALTER TABLE ... CLUSTER BY (cols)。既定では過去に書き込まれたデータには適用されない →OPTIMIZE FULLで強制再クラスタリング。 - パーティションテーブルからの変換(DBR 18.1 以降):
ALTER TABLE ... REPLACE PARTITIONED BY WITH CLUSTER BY [(cols) | AUTO]。ダウンタイム最小、外部/マネージド両対応、変換後は DBR 13.3 LTS 以降で読み取り可。
移行時のキー選択ガイド:
| 現在の手法 | クラスタリングキーの推奨 |
|---|---|
| Hive スタイルパーティション | パーティション列をキーに |
| Z オーダー | ZORDER BY 列をキーに |
| パーティション + Z オーダー | 両方をキーに |
| カーディナリティ削減用の生成列(例: タイムスタンプの日付) | 元の列をキーにし、生成列は作らない |
書き込み時クラスタリングのサイズしきい値(トランザクション内データがこれを超えるとトリガー):
| クラスタリング列数 | UC マネージドテーブル | その他 Delta テーブル |
|---|---|---|
| 1 | 64 MB | 256 MB |
| 2 | 256 MB | 1 GB |
| 3 | 512 MB | 2 GB |
| 4 | 1 GB | 4 GB |
書き込み時クラスタリングに対応する操作: INSERT INTO / CTAS・RTAS / Parquet からの COPY INTO / spark.write.mode("append")。すべての操作でクラスタリングが適用されるわけではないので、OPTIMIZE を頻繁に実行するのが推奨。ストリーミングでは spark.databricks.delta.liquid.eagerClustering.streaming.enabled=true を設定し、直近 5 回のストリーミング更新の少なくとも 1 回がしきい値を超えた場合にトリガー。
OPTIMIZE と OPTIMIZE FULL(増分 vs 全体):
- 液体クラスタリングの
OPTIMIZEは増分(incremental)。クラスタリングが必要なデータのみ書き換え、既にキーに一致するファイルは書き換えない。だからほとんどの OPTIMIZE ジョブは速い。 OPTIMIZE FULL(DBR 16.0 以降): 全レコードを強制再クラスタリング。クラスタリングを初めて有効化したとき、またはキーを変更したときに実行。大きなテーブルでは数時間かかることがある。DBR 18.1 以降はOPTIMIZE FULL WHERE <predicate>で部分再クラスタリング可。- 予測的最適化を使わない場合は定期
OPTIMIZEをスケジュール。更新/挿入が多いテーブルは 1〜2 時間ごとを推奨。
自動液体クラスタリング(CLUSTER BY AUTO):
- DBR 15.4 LTS 以降(UC マネージド Delta)、マネージド Iceberg v3 は DBR 18.0 以降。
- クエリワークロードを分析して最適なキーをインテリジェントに選択・進化。コスト対応(データスキップの削減効果がクラスタリングコストを上回るときだけキーを変更)。
- キーが選ばれないことがある: テーブルが小さすぎる / 既に良いレイアウトがある / 頻繁なクエリがない / DBR 15.4 LTS 未満。
- 自動キー選択とクラスタリング操作の予測的最適化が必要(非同期実行)。
予測的最適化(Predictive Optimization)
UC マネージドテーブル(Delta と Iceberg)に対し OPTIMIZE / VACUUM / ANALYZE を自動実行し、手動メンテナンスと性能追跡の手間を排除します。
- 既定有効化: 2024-11-11 以降に作成されたアカウントは既定で有効。既存アカウントは段階的ロールアウトで 2026 年 8 月までに完了予定。
- 課金: ジョブ用サーバーレスコンピュートで実行。サーバーレスジョブ SKU で課金。
- 前提条件: Premium プランのサポート対象リージョン / SQL ウェアハウスまたは DBR 12.2 LTS 以降 / UC マネージドテーブルのみ。
- 重要な注意: 予測的最適化の
OPTIMIZEはZORDERを実行しない(Z オーダーファイルは無視)。→ Z-ORDER 依存のテーブルは自動最適化の恩恵が限定的。液体クラスタリングへ移行が推奨。 - VACUUM 保持の落とし穴:
delta.deletedFileRetentionDurationの既定 7 日で古いファイルが削除される。長期タイムトラベルが必要なら予測的最適化を有効化する前にこのプロパティを設定する(例:'30 days')。 - 有効化の粒度: アカウント / カタログ / スキーマ / テーブル。継承モデル(
ALTER ... ENABLE | DISABLE | INHERIT PREDICTIVE OPTIMIZATION)。明示的に無効化したオブジェクトは、後からアカウントレベルで有効化してもブロックされたまま。 - スキップ理由の確認(DBR 18 以降):
DESCRIBE TABLE EXTENDED ... AS JSONのpredictive_optimization_evaluationsフィールド(操作種別:COMPACTION/CLUSTERING/AUTO_CLUSTERING_COLUMN_SELECTION/VACUUM)、またはカタログエクスプローラーの「履歴」タブ(自動 = 実行、未適用 = スキップ)。結果反映まで最大 24 時間。 - 監視システムテーブル:
system.storage.predictive_optimization_operations_history。 - 実行されないテーブル: OpenSharing 受信者テーブル、外部テーブル。
VACUUM
保持しきい値より古く、参照されなくなったデータファイルを物理削除します。コスト削減とコンプライアンス(削除レコードの完全消去)に重要。
- 既定保持期間 = 7 日。UniForm(Iceberg 読み取り)有効時は到達不能な Iceberg メタデータもクリーンアップ。予測的最適化が UC マネージドテーブルで自動実行。
- 構文:
VACUUM table_name/ プレビューはVACUUM table_name DRY RUN。 - 保持しきい値の安全性(試験頻出): Databricks は保持間隔 7 日以上を強く推奨。数日実行のジョブがある場合、短すぎる保持だと未コミットのファイルが削除される恐れ。危険な実行を防ぐ安全チェックがあり、必要なら
SET spark.databricks.delta.retentionDurationCheck.enabled = false(Iceberg はspark.databricks.iceberg.retentionDurationCheck.enabled)で無効化できる(自己責任)。 - タイムトラベルへの影響: VACUUM 実行で保持期間を過ぎたバージョンはクエリできなくなる。
- ログファイル: チェックポイント後に非同期削除。既定保持 30 日(VACUUM 管理外)。
- ディスクキャッシュ: VACUUM で削除された Parquet がキャッシュに残り、削除済みバージョンをクエリできてしまうことがある → クラスター再起動でキャッシュ消去。
- 削除ベクトル/論理削除:
REORG TABLE ... APPLY (PURGE)で物理書き換えを強制 → その後遅延を置いてVACUUM(古いファイルが期限切れになるのを待つため)。 - LITE / FULL モード(DBR 16.4 LTS 以降、パブリックプレビュー):
LITEはトランザクションログのみで削除対象を特定し、全ファイル一覧を避けて高速・低コスト(大規模・高頻度テーブル向け)。FULLが既定。LITE の要件: ログ保持しきい値(既定 30 日)内に少なくとも 1 回の成功した VACUUM 実行が必要。 - クラスターサイズ推奨: フェーズ 1 はワーカー並列でファイル一覧、フェーズ 2 はドライバー単独で削除。→ 1〜4 ワーカー(各 8 コア)で自動スケーリング + 8〜32 コアのドライバー。定期的に 10,000 超のファイル削除や 30 分超の処理ならドライバー/ワーカーを増やす。OOM 回避にはドライバーを大きく。
- バージョン境界: DBR 18.0 以降は
deletedFileRetentionDurationテーブルプロパティで保持制御。UC マネージドテーブルは DBR 12.2 以降で適用。 - 監査:
DESCRIBE HISTORY。spark.databricks.delta.vacuum.logging.enabledで制御。
ファイルサイズ調整(tune-file-size)
- UC マネージドテーブルは既定でファイルサイズを自動チューニング(手動チューニング推奨は外部/レガシー向け)。
- 自動圧縮(Auto Compaction): 書き込み成功後、書き込みクラスターで同期実行。未圧縮ファイルのみ結合。設定:
autoOptimize.autoCompact(テーブル)/spark.databricks.delta.autoCompact.enabled(セッション)。オプション:auto(推奨、他の自動チューニングを考慮)/legacy(=trueの別名)/true(ターゲット 128 MB 固定)/false。 - 最適化された書き込み(Optimized Writes): 書き込み前にシャッフルしてファイルサイズを改善。パーティションテーブルで特に有効。
autoOptimize.optimizeWrite/spark.databricks.delta.optimizeWrite.enabled。true= 128 MB。MERGE/ サブクエリ付きUPDATE・DELETEでは常に有効(オフ不可)。SQL ウェアハウスではCTAS/INSERTでも有効。 - ターゲットファイルサイズ:
delta.targetFileSize(例104857600バイト or100mb)。 - テーブルサイズによる自動チューニング(試験に出やすい数値):
- 2.56 TB 未満 → ターゲット 256 MB
- 2.56 TB〜10 TB → 256 MB から 1 GB へ線形に増加
- 10 TB 超 → 1 GB
OPTIMIZEは 1 TB 超のテーブルではスケジュール実行を推奨(自動圧縮/最適化書き込みは OPTIMIZE の完全な代替ではない)。- 行数制限:
spark.sql.files.maxRecordsPerFile(または DataFrameWriter のmaxRecordsPerFile)。エラー回避が必要な狭いテーブル以外は非推奨。
3-3. Spark の性能(シャッフル/スキュー/スピル、AQE、Photon、キャッシュ、ブロードキャスト)
シャッフル・スキュー・スピルの診断(Spark UI)
診断は「長いステージ」を開き、まずスピル、次にスキューを確認します。
- スピル(spill): Spark がメモリ不足のとき、メモリからディスクへデータを移動する処理。非常にコストが高く、データシャッフル中に最も起きやすい。ステージページ上部にスピル統計(Spill Memory / Spill Disk)が出る。統計が出なければそのステージにスピルはない。
- スキュー(skew): 1 つまたは少数のタスクが他より極端に長い状態。「概要メトリクス」で最大(max)継続時間が 75 パーセンタイルより大幅に長いかを見る。最大が 75 パーセンタイルより 50% 以上長ければスキューの可能性が高い。正常なステージは 75 パーセンタイルと最大がほぼ同じ。
- シャッフル(shuffle): ノード間のデータ交換。分散処理のオーバーヘッドの主因で、線形スケーラビリティを崩す。スピル/スキューの温床。
対処の方向性: スピルはメモリ最適化インスタンスや適切なパーティション数で軽減、スキューは AQE のスキュー結合処理や再パーティションで緩和。
アダプティブクエリ実行(AQE)
実行中に、シャッフル/ブロードキャスト交換(クエリステージ)の終端で得た実測統計に基づいてクエリを再最適化します。統計が無い/古い、複雑クエリの途中、スキュー発生後など、静的統計が不正確なときに特に有効。既定で有効。
4 つの主要機能:
- ソートマージ結合 → ブロードキャストハッシュ結合への動的切り替え
- シャッフル後のパーティションの動的結合(coalesce): 小さすぎるパーティション/タスクを合理的サイズに結合(I/O とスケジューリングのオーバーヘッド削減)
- スキュー結合の動的処理: 偏ったタスクをほぼ均等サイズに分割(必要ならレプリケート)。ソートマージ結合とシャッフルハッシュ結合に適用
- 空リレーションの動的検出と伝播
適用条件: 非ストリーミングであり、少なくとも 1 つの交換(結合/集計/ウィンドウ)またはサブクエリを含む。適用対象でも必ず再最適化されるとは限らない(プランが変わるかは統計次第)。
主な構成パラメータ(既定値を覚える):
| プロパティ | 意味 | 既定値 |
|---|---|---|
spark.databricks.optimizer.adaptive.enabled | AQE の有効/無効 | true |
spark.sql.shuffle.partitions | シャッフル時の既定パーティション数。auto で自動最適化シャッフル | 200 |
spark.databricks.adaptive.autoBroadcastJoinThreshold | 実行時にブロードキャスト結合へ切替えるしきい値 | 30MB |
spark.sql.adaptive.coalescePartitions.enabled | パーティション結合の有効/無効 | true |
spark.sql.adaptive.advisoryPartitionSizeInBytes | 結合後のターゲットサイズ | 64MB |
spark.sql.adaptive.coalescePartitions.minPartitionSize | 結合後の最小パーティションサイズ | 1MB |
spark.sql.adaptive.coalescePartitions.minPartitionNum | 結合後の最小パーティション数(非推奨、上書き用) | クラスターコア数の 2 倍 |
spark.sql.adaptive.skewJoin.enabled | スキュー結合処理の有効/無効 | true |
spark.sql.adaptive.skewJoin.skewedPartitionFactor | スキュー判定の係数(中央値への倍率) | 5 |
spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes | スキュー判定のサイズしきい値 | 256MB |
spark.databricks.adaptive.emptyRelationPropagation.enabled | 空リレーション伝播 | true |
スキュー判定条件: パーティションが「サイズ > skewedPartitionFactor(5) × 中央値サイズ」かつ「サイズ > skewedPartitionThresholdInBytes(256MB)」の両方を満たすとき、偏っていると見なす。
FAQ の要点(Professional で問われる判断):
- AQE でもブロードキャストヒントは使うべき。静的計画のブロードキャスト結合の方が通常速い(AQE は両側のシャッフルが済むまで切り替えないことがある)。ヒントを使っても動的最適化は併用される。
- スキュー結合はヒントより AQE の自動処理を優先(完全自動で一般に高性能)。
- AQE は結合順序の自動変更(動的結合並べ替え)は行わない。
- ブロードキャストされない理由: 結合種別が非対応(例:
LEFT OUTER JOINの左側はブロードキャスト不可)、空パーティションが多い(spark.sql.adaptive.nonEmptyPartitionRatioForBroadcastJoin未満)。
Photon
Databricks ネイティブのベクトル化クエリエンジン。SQL ワークロードと DataFrame API 呼び出し(インジェスト/ETL/ストリーミング/データサイエンス/対話型)を高速化。Spark API 互換でコード変更・ロックインなし。SQL ウェアハウスでは既定で有効、サーバーレスジョブでも自動有効。高速化はコスト削減につながるため、定期ジョブは「Photon で速くかつ安くなるか」を評価する。
キャッシュの使い分け
- ディスクキャッシュ(disk cache、旧 Delta キャッシュ): ローカル SSD にリモートデータのコピー。ファイル作成/削除を自動検知して更新。SSD ボリュームのワーカータイプを選ぶだけで有効化(最も簡単で推奨)。任意のサブクエリ結果は保存できない。
- Spark キャッシュ(
.persist()/.unpersist())は避ける: サブクエリ結果や非 Parquet 形式を保持できるが、誤用でメモリを食い遅くする。 - クエリ結果キャッシュ(query result cache): SQL ウェアハウスのクラスター単位。決定論的クエリ(
= NOW()等を避ける)で、基のデータが Delta 形式で未変更なら結果を直接返す。 - Databricks SQL UI キャッシュ: SQL UI のクエリ結果をユーザー単位でキャッシュ。
ブロードキャスト結合
小さいテーブルを全 Executor に配布してシャッフルを回避する結合。AQE が実行時に自動採用(既定 30MB)。既知のクエリでは明示的なブロードキャストヒントも有効。
その他の性能ベストプラクティス(クエリ側)
- ネイティブ Spark 関数を優先(UDF 回避): Python-Spark 間のシリアル化でクエリが大幅に遅くなる。必要なら Pandas UDF(Apache Arrow で効率的に転送)。
- ANALYZE TABLE で統計収集: CBO が最適プラン・結合種別・ビルド側・結合順序を選ぶのに使う。予測的最適化は
ANALYZEを自動実行(パブリックプレビュー)。 - データスキップ: 既定で先頭 32 列の統計を収集。Databricks はデータスキップに液体クラスタリングを推奨。
3-4. パフォーマンス効率のベストプラクティス(クラスターサイズ、パーティション設計)
スケーリングの基礎概念
- 垂直スケーリング(vertical scaling): 1 台のマシンに CPU/メモリ/GPU を増減。より大きなマシンが無い/次のサイズが極端に高価、という限界がある。
- 水平スケーリング(horizontal scaling): クラスターにノードを増減。垂直の限界を超える解。Spark/Photon が負荷分散を担う。ノード数に技術的上限はないが、多いほど管理が複雑化。
- 線形スケーラビリティ(linear scalability): リソースとスループットが線形。並列タスクが独立なときのみ成立。ノード間データ交換(シャッフル)があると崩れる。小さいデータは分散でかえって遅くなることも。
コンピュートサイズ設計
Databricks はワーカーノードごとに 1 Executor(Executor = ワーカー)。サイズ検討では以下を見る:
- Executor 合計コア数(コンピュート): 最大並列度を決める。
- Executor 合計メモリ: ディスクへスピルする前にメモリ保持できる量。
- Executor ローカルストレージ: シャッフル/キャッシュ時のスピルに使う。
考慮点: データ量、計算の複雑さ、読み取り元、外部ストレージのパーティション方式、必要な並列度。
「より大きなクラスターを優先する」(試験頻出の考え方): ワークロードの拡大が線形なら、大きいクラスターでも小さいクラスターよりコストは同じで速いだけ(クラスターは利用時間分だけ課金。2 ワーカー×1 時間 = 4 ワーカー×30 分)。SLA が柔軟でコスト最優先なら自動スケーリングが最安になりやすいが、最速とは限らない。サーバーレスでは自動管理のため「大きく」は必須ではない。
ワークロード別のクラシックコンピュートサイズの目安:
- 開発/テスト: 単一ノード or 小規模(2〜4 ワーカー)+ 自動スケール
- バッチ ETL: 中規模(8〜16 ワーカー)+ メモリ最適化 + 自動スケール
- ストリーミング: 小〜中規模(4〜8 ワーカー)+ 自動スケール
- ML: モデル/データ量に応じた GPU インスタンス
- SQL ウェアハウス: 同時実行ユーザー数とクエリ複雑度でサイズ決定。小〜中から始めて自動スケール。サーバーレス SQL ウェアハウスで即時起動と自動スケール。
インスタンスファミリの選び方:
- メモリ最適化: シャッフル/スピルが多い ML
- コンピュート最適化: ストリーミング、メンテナンスジョブ(OPTIMIZE / VACUUM)
- ストレージ最適化: キャッシュが効くアドホック/対話型分析
- GPU 最適化: 特定の ML/DL
- 汎用: 特定要件がない場合
パーティション設計(試験頻出の数値)
- パーティションは静的でファイルシステム階層になり、アクセスパターンの変化に追随しづらい。過剰パーティション(小さすぎるファイル × 多すぎるパーティション)はクエリを遅くする。
- 1 TB 未満のテーブルはパーティション分割しない。
- パーティションするなら各パーティションのデータが 1 GB 以上になる見込みの列で。
- 新しい Delta テーブルはパーティションではなく液体クラスタリングを推奨。
その他のパフォーマンス設計
- データインジェスト/アクセスパターンの理解: 大きいファイルはスキャン向き、小さいファイルは検索(特定行取得)向き。DML はデータがクラスター化・分離可能なとき最も速い。インジェスト時に自然な時間順を保ち、可能な限りフィルターを効かせる。
- 並列計算: SQL は自動並列化。Lakeflow パイプライン、Spark 上の Pandas API、MLlib、DeepSpeed/TorchDistributor。
- 実行チェーン全体を分析(BI ツール → コネクタ → SQL エンジン)。
- 予測的最適化と UC マネージドテーブルを使う(自動でレイアウト最適化・クリーンアップ)。
- 範囲結合の最適化と AQE(3-3 参照)。
- パフォーマンステスト: 本番同等データ(ボリューム/レイアウト/スキュー)で実施。事前ウォーミング(クラスタープール、キャッシュ)を考慮。最初のクエリは常に遅い。ボトルネックを設計時に特定。
- 監視: システムテーブル(
system.compute/system.workflow/system.query)、Spark イベントログ(長ステージ・スキュー・過剰シャッフル・OOM)、クエリプロファイル、SQL ウェアハウス監視、構造化ストリーミング監視、ジョブ監視。
3-5. コスト最適化(DBU、コンピュート選択、コスト配分、監視)
コスト最適化の 4 原則
- 最適なリソースを選択する: 最良の価格/パフォーマンス比を選ぶ。
- リソースを動的に割り当てる: 未使用/低使用率を特定し、再構成・統合・停止。
- コストの監視と制御: 各リソースを監視してベースラインを作り、ワークロード所有者に透過的にコスト配分。
- コスト効率の高いワークロードを設計する: 自動スケーリング前提。使用量とパフォーマンスメトリクスで初期インスタンス数を決める。
1. 最適なリソースを選択する
- Delta Lake を使う: Parquet/ORC/JSON より高速でシンプルな ETL。ジョブコンピュートの稼働時間短縮 = コスト削減。
- ジョブコンピュート(Jobs Compute)を使う: 非対話型ワークロードは汎用(All-Purpose)コンピュートより大幅に安い。ジョブごとに新規インスタンスで分離、マルチタスクジョブはコンピュート再利用可。
- SQL ワークロードには SQL ウェアハウス: 対話型 SQL で最もコスト効率が良い。全 SQL ウェアハウスに Photon 標準。サーバーレス SQL ウェアハウスはインテリジェントワークロード管理(IWM)対応。
- 最新の DBR を使う: メジャーリリースごとに性能向上 = コンピュート効率化 = コスト削減。
- GPU は適切なワークロードのみ: GPU アクセラレーテッドライブラリを使うワークロードだけ。コンピュートポリシーで不要な GPU 利用を制限。
- サーバーレスを使う: BI は急峻・同時多発。非サーバーレス SQL ウェアハウスは起動に数分でアイドル終了されにくい → サーバーレス SQL ウェアハウスは数秒起動・高速縮小でコスト削減。モデルサービングもサーバーレスで自動スケール。
- 適切なインスタンス種別: 最新世代を使う。ML/シャッフル多=メモリ最適化、ストリーミング/メンテ=コンピュート最適化、キャッシュ=ストレージ最適化、ML/DL=GPU、その他=汎用。
- 効率的なコンピュートサイズ: Executor 合計コア/メモリ/ローカルストレージで検討。デプロイ時にサイズ標準とポリシー(T シャツサイズ: Small/Medium/Large)を確立。
- Photon を評価: 速度向上がコスト削減につながるか、定期ジョブで評価。
2. リソースを動的に割り当てる
- 自動スケーリング: ジョブ特性に応じワーカーを動的増減。静的サイズよりコスト削減。ストリーミングは縮小に制限 → Lakeflow パイプラインの強化自動スケーリングを推奨。
- 自動終了: 対話型コンピュートに設定。営業時間限定なら自動終了 + スケジュール起動/事前ウォーミング。
- クラスタープール: アイドル状態の即利用インスタンス群。起動/自動スケール時間を短縮。プール内でアイドルの間は DBU 課金なし(インスタンスプロバイダー課金は発生)。
- コンピュートポリシー: 最小ワーカー数付き自動スケール、妥当な自動終了(例 1 時間)、コスト効率の良い VM のみ許可、スポット戦略の適用を強制。
3. コストを監視して制御する
- タグ付けによるコスト配分: ワークスペース/クラスター/SQL ウェアハウス/プールにタグ。命名規則を作り、
Business Units/Projectsは最低限、必要ならEnvironment(開発/QA/本番)も。タグは使用状況ログとクラウドプロバイダーリソース双方に伝播。タグは将来分にのみ効き、過去に遡って追加できない → 最初から細かめに始める。総コスト = DBU + VM + ディスク + ネットワーク(サーバーレスは DBU に VM 込み)。 - 予算(budgets)とアラート: アカウント全体の使用状況を監視。フィルターでチーム/プロジェクト/ワークスペース単位に。毎月の予算到達でメール通知を設定。サーバーレスは使用ポリシー(budget policies)で帰属。
- 監視ツール:
- アカウントコンソールのコスト管理 AI/BI ダッシュボード
- システムテーブル
system.billing.usage(カスタムタグが反映される)。サーバーレス/ジョブ/モデルサービングのコストも監視可。 - Azure Cost Management(コスト分析、Databricks リソースのタグで詳細分析)
- 組織的なコスト管理: タグ整備のハウスキーピングジョブ(監査ログに記録)、定期コスト監査、毎月のコストレポート、チーム教育、コンピュートポリシー。コスト最適化は継続プロセス。
4. コスト効率の高いワークロードを設計する
- 常時稼働 vs トリガーストリーミングのバランス: 低レイテンシ不要の増分ワークロードはトリガー
AvailableNowの構造化ストリーミングを使う(常時稼働の課金を避ける)。 - オンデマンド vs スポットのバランス: スポットインスタンスは余剰 VM を安価に利用(中断リスクあり)。ドライバー(Spark ドライバー、最初のインスタンス)は常にオンデマンドを推奨。中断による遅延を許容できるワークロードに向く。
4. 構文・コード例
OPTIMIZE(ビンパッキング)
sql
-- 基本
OPTIMIZE table_name;
-- パーティション述語でサブセットのみ(WHERE)
OPTIMIZE table_name WHERE date >= '2022-11-18';
-- Z-ORDER(液体クラスタリングを使わない Delta テーブル)
OPTIMIZE table_name ZORDER BY (col_a, col_b);
-- 液体クラスタリングの再クラスタリング強制(DBR 16.0/16.4 LTS 以降)
OPTIMIZE table_name FULL;
-- 部分再クラスタリング(DBR 18.1 以降)
OPTIMIZE events FULL WHERE event_date >= '2025-01-01';python
# Python(Delta 固有)
from delta.tables import *
deltaTable = DeltaTable.forName(spark, "table_name")
deltaTable.optimize().executeCompaction()
deltaTable.optimize().where("date='2021-11-18'").executeCompaction()液体クラスタリング(CLUSTER BY)
sql
-- 作成時にキー指定
CREATE TABLE table1 (col0 INT, col1 STRING) CLUSTER BY (col0);
-- CTAS(CLUSTER BY はテーブル名の後、SELECT の前)
CREATE TABLE table2 CLUSTER BY (col0) AS SELECT * FROM table1;
-- 構造をコピー
CREATE TABLE table3 LIKE table1;
-- 既存テーブルで有効化
ALTER TABLE table_name CLUSTER BY (col1, col2);
-- キーの変更(既存データは書き換えられない)
ALTER TABLE table_name CLUSTER BY (new_col1, new_col2);
-- クラスタリング解除
ALTER TABLE table_name CLUSTER BY NONE;
-- 自動液体クラスタリング
CREATE OR REPLACE TABLE table1 (c1 INT, c2 STRING) CLUSTER BY AUTO;
ALTER TABLE table1 CLUSTER BY AUTO;
-- 初期キーヒント + 自動
ALTER TABLE table1 CLUSTER BY (c1, c2);
ALTER TABLE table1 CLUSTER BY AUTO;
-- パーティションテーブルを液体クラスタリングへ変換(DBR 18.1 以降)
ALTER TABLE t1 REPLACE PARTITIONED BY WITH CLUSTER BY (day, id);
OPTIMIZE t1;
ALTER TABLE t2 REPLACE PARTITIONED BY WITH CLUSTER BY AUTO; -- 現パーティション列から開始し自動進化
ALTER TABLE t3 REPLACE PARTITIONED BY WITH CLUSTER BY; -- 現パーティション列をそのままキーに
-- クラスタリング確認
DESCRIBE TABLE table_name;
DESCRIBE DETAIL table_name;
SHOW TBLPROPERTIES table_name; -- clusterByAuto / clusteringColumns を確認python
# Python DeltaTable API(DBR 14.3 LTS 以降)
(DeltaTable.create()
.tableName("table1")
.addColumn("col0", dataType="INT")
.addColumn("col1", dataType="STRING")
.clusterBy("col0")
.execute())
# DataFrame から(キー設定は作成 or overwrite のみ)
df = spark.read.table("table1")
df.write.clusterBy("col0").saveAsTable("table2")
# 自動液体クラスタリング(Python API は DBR 16.4 以降、作成/置換時のみ)
df.write.format("delta").option("clusterByAuto", "true").saveAsTable("t")
# 構造化ストリーミング書き込み(DBR 16.4 LTS 以降)
(spark.readStream.table("source_table")
.writeStream
.clusterBy("column_name")
.option("checkpointLocation", checkpointPath)
.toTable("target_table"))VACUUM
sql
-- 既定 7 日保持で削除
VACUUM table_name;
-- 削除対象のプレビュー(削除しない)
VACUUM table_name DRY RUN;
-- LITE / FULL モード(DBR 16.4 LTS 以降、プレビュー)
VACUUM table_name LITE;
VACUUM table_name FULL;
-- 保持期間の設定(長期タイムトラベル用、予測的最適化の有効化前に)
ALTER TABLE table_name SET TBLPROPERTIES ('delta.deletedFileRetentionDuration' = '30 days');
-- 論理削除を物理化 → 遅延後に VACUUM
REORG TABLE table_name APPLY (PURGE);
VACUUM table_name;
-- 安全チェックの無効化(自己責任、7 日未満にする場合)
SET spark.databricks.delta.retentionDurationCheck.enabled = false;
-- 監査
DESCRIBE HISTORY table_name;予測的最適化の有効化
sql
ALTER CATALOG catalog_name { ENABLE | DISABLE | INHERIT } PREDICTIVE OPTIMIZATION;
ALTER { SCHEMA | DATABASE } schema_name { ENABLE | DISABLE | INHERIT } PREDICTIVE OPTIMIZATION;
ALTER TABLE table_name { ENABLE | DISABLE | INHERIT } PREDICTIVE OPTIMIZATION;
-- 状態確認
DESCRIBE (CATALOG | SCHEMA | TABLE) EXTENDED name;
-- スキップ理由の確認(DBR 18 以降)
DESCRIBE TABLE EXTENDED catalog_name.schema_name.table_name AS JSON;統計収集(ANALYZE)とファイルサイズ
sql
-- CBO 用の統計収集
ANALYZE TABLE table_name COMPUTE STATISTICS;
ANALYZE TABLE table_name COMPUTE STATISTICS FOR ALL COLUMNS;
ANALYZE TABLE t1 COMPUTE DELTA STATISTICS; -- Delta 統計
-- ターゲットファイルサイズ
ALTER TABLE table_name SET TBLPROPERTIES ('delta.targetFileSize' = '128mb');AQE の構成例
sql
SET spark.databricks.optimizer.adaptive.enabled = true; -- AQE 有効(既定)
SET spark.sql.shuffle.partitions = auto; -- 自動最適化シャッフル
SET spark.databricks.adaptive.autoBroadcastJoinThreshold = 30MB;
SET spark.sql.adaptive.skewJoin.skewedPartitionFactor = 5;
SET spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes = 256MB;自動圧縮 / 最適化された書き込み
sql
-- テーブルプロパティ
ALTER TABLE t SET TBLPROPERTIES ('delta.autoOptimize.autoCompact' = 'auto');
ALTER TABLE t SET TBLPROPERTIES ('delta.autoOptimize.optimizeWrite' = 'true');python
# セッション設定
spark.conf.set("spark.databricks.delta.autoCompact.enabled", "auto")
spark.conf.set("spark.databricks.delta.optimizeWrite.enabled", "true")5. 試験で問われるポイント
Professional 試験は「手法の選択・トレードオフ・自動化・数値境界」を突いてきます。以下は特に狙われる論点です。
- 液体クラスタリング vs パーティション vs Z-ORDER の選択: 新規テーブルは液体クラスタリングが第一推奨。高カーディナリティ列フィルター、スキュー、急成長、同時書き込み、変化するアクセスパターン、パーティション数が極端になるケースで効く。併用不可(パーティション/ZORDER と互換なし)。
- クラスタリングキーの数字: 最大 4 キー。10 TB 未満では多キーが単一列フィルターを遅くする。キーは**統計収集列(先頭 32 列)**である必要。
- OPTIMIZE の増分 vs FULL: 通常
OPTIMIZEは増分。キー変更/初回有効化のときはOPTIMIZE FULL。予測的最適化利用時はスケジュール OPTIMIZE を無効化。 - 予測的最適化の対象と制約:
OPTIMIZE/VACUUM/ANALYZEを自動実行。UC マネージドテーブルのみ、DBR 12.2 LTS 以降、サーバーレスジョブ SKU 課金。ZORDERは実行しない。外部テーブル・OpenSharing 受信者テーブルは対象外。既定有効は 2024-11-11 以降のアカウント。 - VACUUM の 7 日: 既定保持 7 日、7 日以上を強く推奨。短くするとロングランジョブの未コミットファイルを消す恐れ。安全チェックは
retentionDurationCheck。タイムトラベルの可用範囲とストレージコストのトレードオフ。予測的最適化前にdeletedFileRetentionDurationを設定して長期履歴を守る。 - ファイルサイズの自動チューニング数値: <2.56 TB → 256 MB、2.56〜10 TB → 線形に 256 MB→1 GB、>10 TB → 1 GB。自動圧縮/最適化書き込みの
trueは 128 MB 固定。MERGE/サブクエリ付きUPDATE・DELETEでは常に有効(オフ不可)。 - AQE の 4 機能と既定値: ソートマージ→ブロードキャスト切替(30MB)、パーティション結合(advisory 64MB)、スキュー結合(factor 5 かつ 256MB)、空リレーション伝播。AQE は結合順序を変えない。ブロードキャストヒントは AQE でも有効、スキューは AQE 自動処理を優先。
- スキュー/スピルの診断: スピル = メモリ→ディスク退避(シャッフル中に多発)。スキュー = max が 75 パーセンタイルより 50% 以上長いなら疑う。
- コンピュート選択のコスト: 非対話型はジョブコンピュート、対話型 SQL は SQL ウェアハウス、BI/変動負荷はサーバーレス。汎用コンピュートでジョブを流さない。「線形なら大きいクラスターでもコスト同じで速いだけ」。
- DBU と総コスト: 総コスト = DBU + VM + ディスク + ネットワーク。サーバーレスは DBU に VM 込み。プールでアイドル中は DBU 課金なし。
- コスト配分: タグは将来分のみ・遡及不可 → 最初から細かく。
system.billing.usageにタグが反映。予算 + メールアラート。 - スポット戦略: 安価だが中断あり。ドライバーは常にオンデマンド。
- インスタンスファミリの対応: メモリ最適化=シャッフル/スピル多い ML、コンピュート最適化=ストリーミング/メンテ(OPTIMIZE/VACUUM)、ストレージ最適化=キャッシュ効くアドホック、GPU=DL、汎用=一般。
- パーティション設計の数値: 1 TB 未満は非パーティション、各パーティション 1 GB 以上なら列でパーティション可。過剰パーティションは遅い。
- Photon: SQL ウェアハウスで既定有効、コード変更不要、速度向上=コスト削減。
- キャッシュの使い分け: ディスクキャッシュ(SSD ワーカーで自動)を活用、Spark キャッシュは避ける、クエリ結果キャッシュは決定論的クエリで効く。
- Bloom フィルターは非推奨 → 予測 I/O か液体クラスタリング。
- UDF 回避: ネイティブ関数優先、必要なら Pandas UDF(Arrow)。
6. 理解度チェックリスト
- [ ] OPTIMIZE(ビンパッキング)が「べき等」であり、サイズで均等化することを説明できる
- [ ] 液体クラスタリングがパーティション/Z-ORDER を置き換える理由(書き換えなしでキー再定義)を説明できる
- [ ] クラスタリングキーは最大 4 個、統計収集列(先頭 32 列)である必要があることを覚えた
- [ ] 10 TB 未満のテーブルで多キーが単一列フィルターを遅くしうるトレードオフを理解した
- [ ]
CLUSTER BY AUTO(自動液体クラスタリング)の要件(UC マネージド + 予測的最適化、DBR 15.4 LTS 以降)を説明できる - [ ]
OPTIMIZE(増分)とOPTIMIZE FULL(強制再クラスタリング=キー変更/初回)の使い分けを説明できる - [ ] 液体クラスタリングの書き込み時サイズしきい値(UC は他 Delta より低い)を思い出せる
- [ ] 予測的最適化が実行する 3 操作(OPTIMIZE / VACUUM / ANALYZE)と、ZORDER を実行しないことを言える
- [ ] 予測的最適化の前提(UC マネージド、DBR 12.2 LTS 以降、サーバーレス課金、外部テーブル対象外)を挙げられる
- [ ] VACUUM の既定保持 7 日と「7 日以上推奨」の理由(未コミットファイル削除リスク)を説明できる
- [ ] VACUUM とタイムトラベル/ディスクキャッシュ/削除ベクトル(REORG PURGE)の関係を説明できる
- [ ] ファイルサイズの自動チューニング数値(<2.56TB=256MB、>10TB=1GB)と自動圧縮 128MB を覚えた
- [ ] 自動圧縮と最適化された書き込みの違い、MERGE/UPDATE/DELETE で常時有効な点を説明できる
- [ ] シャッフル・スキュー・スピルの定義と Spark UI での見つけ方(max > 75%tile の 50% 増)を言える
- [ ] AQE の 4 機能と主要既定値(30MB / 64MB / factor 5・256MB / 200 or auto)を挙げられる
- [ ] AQE が結合順序を変えないこと、ブロードキャストヒントとスキュー処理の推奨を説明できる
- [ ] Photon の位置づけ(ベクトル化、SQL ウェアハウス既定、コスト削減)を説明できる
- [ ] ディスクキャッシュ・クエリ結果キャッシュ・Spark キャッシュ(回避)の使い分けを説明できる
- [ ] ブロードキャスト結合と CBO(ANALYZE TABLE の統計)の役割を説明できる
- [ ] 「より大きなクラスターを優先」がなぜコスト中立で高速になりうるかを説明できる
- [ ] ジョブコンピュート/SQL ウェアハウス/サーバーレス/汎用の使い分けとコスト差を説明できる
- [ ] DBU と総コストの内訳、サーバーレスの DBU に VM 込み、プールのアイドル無課金を説明できる
- [ ] 自動スケーリング・自動終了・クラスタープール・コンピュートポリシーのコスト効果を説明できる
- [ ] スポットインスタンスの利点/リスクと「ドライバーはオンデマンド」を説明できる
- [ ] タグ付けによるコスト配分(遡及不可、system.billing.usage 反映、予算/アラート)を説明できる
- [ ] パーティション設計の数値(1 TB 未満は非分割、各 1 GB 以上で分割)を覚えた
- [ ] インスタンスファミリ(メモリ/コンピュート/ストレージ/GPU 最適化)とワークロードの対応を言える
- [ ] Bloom フィルター非推奨 → 予測 I/O/液体クラスタリング、UDF 回避 → Pandas UDF を覚えた