Skip to content

確認問題|Professional ② コスト・パフォーマンス最適化(配点 13%)

教材 02-cost-performance.md の内容に基づく確認問題です(全10問)。 Professional では「どの手法を、どのテーブル特性のときに、どのトレードオフを承知で選ぶか」と数値境界が問われます。まず問題を解き、下の「解答・解説」で答え合わせをしてください。

問題

Q1.(シナリオ)新規に作成する Delta テーブルは、カーディナリティの高い user_idevent_time でフィルターされ、データの偏りが大きく、急成長し、同時書き込み要件もある。アクセスパターンは今後変わる見込み。教材が推奨するデータレイアウト手法と、その理由の組み合わせはどれか。

  • A. event_time から生成した event_date 列でパーティション分割し、OPTIMIZE ... ZORDER BY (user_id) を併用する
  • B. 液体クラスタリング(CLUSTER BY)を使う。既存データを書き換えずにクラスタリングキーを再定義できるため、変化するアクセスパターンに追随でき、高カーディナリティ列フィルター・スキュー・急成長・同時書き込みのいずれにも適する。パーティション分割と ZORDER とは併用できない
  • C. パーティション分割・ZORDER・液体クラスタリングの 3 つをすべて有効にして、どのクエリパターンにも対応できるようにする
  • D. Bloom フィルターインデックスを作成して高カーディナリティ列のフィルターを高速化する

Q2. 液体クラスタリングのクラスタリングキーの選択について、教材の記述として正しいものはどれか。

  • A. キーは無制限に指定でき、多いほどデータスキップが効くため常に性能が向上する
  • B. キーには複合型(StructType / MapType / ArrayType)そのものや array_col[0] などの要素を指定するのが推奨される
  • C. キーは最大 4 つまで。統計が収集された列(Delta は既定で先頭 32 列の統計を収集)である必要がある。10 TB 未満の小さいテーブルではキーを多くすると単一列フィルターの性能が落ちうる(4 キーは 2 キーより遅い)ため、クエリフィルターで最もよく使う列を選ぶ
  • D. タイムスタンプから作った日付の生成列を優先的にキーにし、元のタイムスタンプ列はキーにしない

Q3. 既存の Delta テーブルで ALTER TABLE t CLUSTER BY (a, b) を実行してクラスタリングキーを設定・変更した。その後の OPTIMIZE の挙動と必要な操作として正しいものはどれか。

  • A. 通常の OPTIMIZE増分でクラスタリングが必要なデータのみ書き換えるため、既定では過去に書き込まれたデータは再クラスタリングされない。クラスタリングを初めて有効化したときやキーを変更したときOPTIMIZE t FULL で全レコードの再クラスタリングを強制する
  • B. ALTER TABLE ... CLUSTER BY の実行時点で既存データがすべて自動的に書き換えられるので、追加操作は不要
  • C. OPTIMIZE はキー変更後は必ず全レコードを書き換えるため、OPTIMIZE FULLOPTIMIZE の動作差はない
  • D. キーを変更した場合は VACUUM を実行することで再クラスタリングされる

Q4. Unity Catalog マネージドテーブルの「予測的最適化(Predictive Optimization)」について、正しい説明はどれか。

  • A. OPTIMIZE / VACUUM / ANALYZE に加えて ZORDER も自動実行するため、Z オーダーに依存したテーブルでも恩恵を最大限受けられる
  • B. 外部テーブルにも適用され、専用のジョブクラスターで同期的に実行される
  • C. 有効化するとタイムトラベル可能範囲が自動的に無期限に延長されるため、delta.deletedFileRetentionDuration の設定は不要
  • D. OPTIMIZE / VACUUM / ANALYZE を自動実行するが ZORDER は実行しないUC マネージドテーブルのみが対象(外部テーブル・OpenSharing 受信者テーブルは対象外)で、ジョブ用サーバーレスコンピュートで非同期実行され、サーバーレスジョブ SKU で課金される

Q5. VACUUM の保持しきい値に関する説明として、正しいものはどれか。

  • A. 既定の保持期間は 24 時間で、実行してもタイムトラベルには影響しない
  • B. 既定の保持期間は 7 日で、Databricks は 7 日以上を強く推奨する。数日実行されるジョブがある場合、保持期間が短すぎると未コミットのファイルが完了前に削除される恐れがある。危険な実行を防ぐ安全チェックがあり、必要なら spark.databricks.delta.retentionDurationCheck.enabled = false で無効化できる(自己責任)。実行すると保持期間を過ぎたバージョンはクエリできなくなる
  • C. 既定の保持期間は 30 日で、_delta_log ディレクトリのログファイルも VACUUM が削除する
  • D. 保持期間は無期限が既定で、明示的に日数を指定しない限り何も削除されない

Q6. ファイルサイズの自動チューニングと自動圧縮/最適化された書き込みについて、正しい説明はどれか。

  • A. テーブルサイズによる自動チューニングは、10 TB 未満なら 128 MB、10 TB 超なら 256 MB がターゲットになる
  • B. 自動圧縮(Auto Compaction)は書き込み前にシャッフルしてファイルサイズを整える機能で、最適化された書き込み(Optimized Writes)は書き込み後に小さいファイルを結合する機能である
  • C. 自動チューニングのターゲットは「2.56 TB 未満 → 256 MB」「2.56 TB〜10 TB → 256 MB から 1 GB へ線形に増加」「10 TB 超 → 1 GB」。autoOptimize.autoCompact / optimizeWritetrue にした場合のターゲットは 128 MB 固定で、MERGE およびサブクエリ付き UPDATE / DELETE では最適化された書き込みが常に有効(オフにできない)
  • D. spark.sql.files.maxRecordsPerFile の設定が Databricks の推奨であり、ターゲットファイルサイズによる制御は非推奨である

Q7. アダプティブクエリ実行(AQE)について、教材の記述と既定値の組み合わせとして正しいものはどれか。

  • A. 4 機能は「ソートマージ結合 → ブロードキャストハッシュ結合への動的切り替え(既定 30MB)」「シャッフル後のパーティションの動的結合(advisory 64MB)」「スキュー結合の動的処理(factor 5 かつ 256MB の両方を満たすとき偏りと判定)」「空リレーションの動的検出と伝播」。AQE は結合順序の自動変更(動的結合並べ替え)は行わない。既知のクエリではブロードキャストヒントを併用すべきだが、スキューはヒントより AQE の自動処理を優先する
  • B. AQE は既定で無効なので、spark.databricks.optimizer.adaptive.enabled = true を明示的に設定する必要がある
  • C. AQE が結合順序を動的に並べ替えるため、ANALYZE TABLE による統計収集は不要になる
  • D. AQE を有効にするとブロードキャストヒントは無視されるため、ヒントは削除すべきである

Q8.(シナリオ)遅いジョブを Spark UI で調べた。ステージ一覧を Duration でソートして最長ステージを開くと、ページ上部に Spill (Memory) / Spill (Disk) の統計が表示され、Summary Metrics ではタスク所要時間の Max が 75 パーセンタイルの 2 倍になっていた。この診断と対処の方向性として最も適切なものはどれか。

  • A. スピル統計が出ている=正常動作なので対処は不要。Max と 75 パーセンタイルの差はタスク数が多いことを示すだけである
  • B. Max が 75 パーセンタイルより 50% 以上長ければスキューだが、スピルはディスク容量不足が原因なのでディスクを増設する
  • C. スピルはメモリ不足でメモリ→ディスクへ退避する処理で、シャッフル中に最も起きやすい。スキューは「Max が 75 パーセンタイルより 50% 以上長い」なら疑う。両方が出ているのでまずスキューだけを解消すればスピルも自動的に消える
  • D. スピル(メモリ不足によるメモリ→ディスク退避、シャッフル中に多発)とスキュー(Max が 75 パーセンタイルより 50% 以上長い)の両方が起きている。AQE を有効に保ってスキュー結合処理・パーティション結合を効かせ、メモリ最適化インスタンスや適切なパーティション数でスピルを軽減し、データスキップ/液体クラスタリングでシャッフル量そのものを減らす

Q9.(シナリオ)毎晩 2 時間かかる非対話型のバッチ ETL を、汎用(All-Purpose)コンピュート上のスケジュールジョブとして実行している。コスト効率を改善したい。教材の考え方として正しいものはどれか。

  • A. 汎用コンピュートのままワーカー数を半分にすれば、実行時間は 2 倍になるが総コストは半分になる
  • B. 非対話型ワークロードはジョブコンピュートに移すべき(汎用より大幅に安い)。またワークロードの拡大が線形なら「大きいクラスターでもコストは同じで速いだけ」(2 ワーカー×1 時間 = 4 ワーカー×30 分)なので、大きいクラスターを優先してよい。SLA が柔軟でコスト最優先なら自動スケーリングが最安になりやすいが最速とは限らない
  • C. 対話型 SQL 向けの SQL ウェアハウスに移すのが、あらゆるワークロードで最もコスト効率が良い
  • D. 汎用コンピュートは複数ジョブでリソースを共有できるため、コスト効率の観点でジョブコンピュートより優れている

Q10. DBU・コスト配分・スポットインスタンスに関する説明として、正しいものはどれか。

  • A. 総コストは DBU のみで構成され、VM・ディスク・ネットワークの費用は含まれない
  • B. クラスタープールにインスタンスがアイドルで待機している間も DBU が課金される
  • C. 総コスト = DBU + VM + ディスク + ネットワーク(サーバーレスは DBU に VM 込み)。プール内でアイドルの間は DBU 課金なし(インスタンスプロバイダー課金は発生)。タグ付けによるコスト配分は将来分にのみ効き、過去に遡って追加できないため最初から細かく設計する。タグは system.billing.usage に反映される。スポットインスタンスは安価だが中断リスクがあり、ドライバーは常にオンデマンドを推奨
  • D. タグは過去の使用状況にも遡って適用されるため、必要になった時点で付与すれば十分である

解答・解説

Q1. 正解: B Databricks は「新しいテーブルはパーティションや ZORDER ではなく液体クラスタリングを使う」ことを一貫して推奨している。液体クラスタリングが特に効くのは、①カーディナリティの高い列でフィルターするクエリ、②データの偏り(スキュー)が大きいテーブル、③急成長しメンテを要するテーブル、④同時書き込み要件のあるテーブル、⑤アクセスパターンが多様/変化するテーブル、⑥典型的なパーティションキーだとパーティションが多すぎ/少なすぎになるテーブル —— まさに本シナリオの条件。液体クラスタリングはパーティション分割・ZORDER と互換性がなく併用不可なので A・C は誤り。また移行ガイドでは「カーディナリティ削減用の生成列は作らず、元の列をキーにする」とされている。D の Bloom フィルターインデックスは非推奨で、代わりに予測 I/O または液体クラスタリングを使う。

Q2. 正解: C クラスタリングキーは最大 4 個、任意の順序で定義でき、統計が収集された列(既定で先頭 32 列)である必要がある。10 TB 未満の小さいテーブルではキーが多いほど単一列フィルターの性能が落ちうる(4 キーは 2 キーより遅い)が、テーブルが大きくなると単一列クエリでの差はごくわずかになる。高相関の 2 列は片方だけをキーにする。B は複合型そのものや配列/マップ要素はキーにできない点で誤り(構造体フィールドのドット表記は可)。D は移行ガイドの推奨と逆(生成列ではなく元の列をキーにする)。

Q3. 正解: A 液体クラスタリングの OPTIMIZE増分で、クラスタリングが必要なデータのみを書き換え、既にキーに一致するファイルは書き換えない。だからほとんどの OPTIMIZE ジョブは高速に終わる。一方、既存テーブルでクラスタリングを有効化したりキーを変更しても、既定では過去に書き込まれたデータには適用されない。全レコードの再クラスタリングを強制するには OPTIMIZE ... FULL を使い、これは「クラスタリングを初めて有効化したとき」「キーを変更したとき」に実行する(大きなテーブルでは数時間かかることがある)。以前に OPTIMIZE FULL を実行済みでキー変更がなければ OPTIMIZE FULL は通常の OPTIMIZE と同じ増分動作になる(C が誤りである理由)。D の VACUUM は未使用ファイル削除であり無関係。

Q4. 正解: D 予測的最適化は UC マネージドテーブルに対し OPTIMIZE / VACUUM / ANALYZE を自動実行するが、ZORDER は実行しない(Z オーダーファイルは無視される)ため、Z オーダー依存のテーブルは自動最適化の恩恵が限定的で、液体クラスタリングへの移行が推奨される(A が誤りである理由)。対象は UC マネージドテーブルのみで、外部テーブルと OpenSharing 受信者テーブルは対象外(B が誤り)。実行はジョブ用サーバーレスコンピュートでの非同期実行で、サーバーレスジョブ SKU で課金される。C は逆で、VACUUM の既定保持 7 日により古いファイルが削除されるため、長期タイムトラベルが必要なら予測的最適化を有効化する前に delta.deletedFileRetentionDuration(例 '30 days')を設定しておく必要がある。

Q5. 正解: BVACUUM の既定保持期間は 7 日delta.deletedFileRetentionDuration)で、Databricks は 7 日以上を強く推奨する。数日実行されるジョブが未コミットのファイルを書き込んでいると、保持期間が短すぎるとジョブ完了前にそれらが削除される恐れがあるためである。危険な VACUUM を防ぐ安全チェックがあり、必要なら retentionDurationCheck を無効化できるが自己責任。実行後は保持期間を過ぎたバージョンへのタイムトラベルができなくなる。C については、ログファイルはチェックポイント後に非同期削除され既定保持 30 日で、VACUUM の管理外。また _ で始まるディレクトリはスキップされる。

Q6. 正解: C テーブルサイズによる自動チューニングのターゲットは「2.56 TB 未満 → 256 MB」「2.56 TB〜10 TB → 256 MB から 1 GB へ線形に増加」「10 TB 超 → 1 GB」。自動圧縮・最適化された書き込みを true(レガシー相当)にした場合のターゲットは 128 MB 固定。MERGE およびサブクエリ付き UPDATE / DELETE では最適化された書き込みが常に有効でオフにできない点も頻出。B は 2 機能の説明が逆で、最適化された書き込みが「書き込み前にシャッフルしてファイルサイズを整える」(パーティションテーブルで特に有効)、自動圧縮が「書き込み成功後に同期的に小さいファイルを結合する(未圧縮ファイルのみ)」。D の maxRecordsPerFile はエラー回避が必要な狭いテーブル以外は非推奨。

Q7. 正解: A AQE は既定で有効(B が誤り)で、①ソートマージ結合→ブロードキャストハッシュ結合への動的切り替え(spark.databricks.adaptive.autoBroadcastJoinThreshold 既定 30MB)、②シャッフル後のパーティションの動的結合(advisoryPartitionSizeInBytes 既定 64MB、最小 1MB)、③スキュー結合の動的処理(skewedPartitionFactor 既定 5 かつ skewedPartitionThresholdInBytes 既定 256MB両方を満たすとき偏りと判定)、④空リレーションの動的検出と伝播 —— の 4 機能を持つ。公式 FAQ は「動的結合の順序変更は AQE の一部ではない」「静的計画のブロードキャスト結合の方が通常速いのでヒントは使うべき(AQE でもヒントは考慮され、動的最適化も併用される)」「スキューはヒントより AQE の自動処理を推奨」と述べている。よって C・D は誤り。ANALYZE TABLE の統計は CBO が結合種別・ビルド側・結合順序を選ぶために依然必要。

Q8. 正解: D Spark UI での診断順序は「ジョブタイムライン → 最長ステージ → スピル → スキュー → I/O 依存か → その他」。スピルは Spark がメモリ不足のときメモリからディスクへデータを退避する処理で、非常にコストが高く、データシャッフル中に最も起きやすい(統計が表示されなければそのステージにスピルはない)。スキューは Summary Metrics のタスク所要時間で「Max が 75 パーセンタイルより 50% 以上長い」なら可能性が高い(健全なステージは 75 パーセンタイルと Max がほぼ同じ)。対処は AQE のスキュー結合処理・パーティション結合を効かせる、メモリ最適化インスタンスや適切なパーティション数、データスキップ/液体クラスタリングでシャッフル量を減らす、など。A はスピルを正常動作としている点、B はスピルの原因をディスク容量不足としている点が誤り。

Q9. 正解: B コスト最適化の原則は「非対話型ワークロードにはジョブコンピュートを使う(汎用より大幅に安い)」「対話型 SQL には SQL ウェアハウス」「BI/変動負荷にはサーバーレス」であり、汎用コンピュートでジョブを流さないのが基本。加えて「より大きなクラスターを優先する」という考え方があり、ワークロードの拡大が線形ならクラスターは利用時間分だけ課金されるため「2 ワーカー×1 時間 = 4 ワーカー×30 分」でコストは同じで速いだけになる(A のように小さくしても総コストは減らない)。SLA が柔軟でコスト最優先なら自動スケーリングが最安になりやすいが最速とは限らない。C は SQL ウェアハウスが対話型 SQL に最もコスト効率が良いという文脈を「あらゆるワークロード」に拡大しており誤り。D も汎用コンピュートを推奨する点で誤り(system.billing.usageusage_metadata.job_id も汎用コンピュートでは設定されず、コスト帰属が不正確になる)。

Q10. 正解: C 総コスト = DBU + VM + ディスク + ネットワークで、サーバーレスは DBU に VM が込みクラスタープール内でアイドルの間は DBU 課金なし(インスタンスプロバイダー課金のみ発生)なので B は誤り。タグ付けによるコスト配分は将来分にのみ効き、過去に遡って追加できないため、最初から細かめに始めるのが定石(D が誤り)。タグは使用状況ログとクラウドプロバイダーリソース双方に伝播し、system.billing.usage に反映される。スポットインスタンスは余剰 VM を安価に使えるが中断リスクがあり、ドライバー(最初のインスタンス)は常にオンデマンドが推奨。