テクテク日記

テクテク=テクノロジー&一歩ずつ(テクテク)https://aka.ms/techtech2 より、カテゴリー別にフィルターできるようになります。

Power BI Direct Lake vs Databricks SQL: アーキテクチャ上のトレードオフとパフォーマンスの考察 ①

Power BI の Direct Lake と DQ on Databricks SQL(DirectQuery on Databricks SQL Warehouse)は、いずれもデータレイク上の大規模データを高速に分析できる一方で、前提とするアーキテクチャや最適化の考え方は大きく異なります。本ブログでは、顧客が実際に使用する数十億行規模の実データを用いた検証結果をもとに、Direct Lake と Databricks SQL それぞれが得意とするパターン、性能が頭打ちになる条件、データ構造・パーティション・ファイル配置の影響を整理します。加えて、Power BI Direct Lake と Databricks の連携を模索している方に向けて、ミラーリングされた Unity Catalog(UC)や外部テーブルショートカットを用いた構成も含めて検証し、どのような前提や制約のもとで有効に機能するのかを考察します。単なる性能比較に留まらず、「どのシナリオで、どの選択が合理的か」を判断するためのトレードオフを分かりやすく解説します。

なお、内容が膨大につき、2回に分けて紹介することにします。また、結果だけ知りたい方は、「パフォーマンス比較」を直接ご覧ください。

前置き

実際に話を進める前に、以下3つのポイントを把握しておく必要があります。

  1. 今回の事例は、顧客が実際に利用している特定時点のデータを用いた PoC の結果。都合により、
    • DirectQuery vs Direct Lake に掛かる物理的なコスト比較は対象外
    • ロードテスト(ストレステスト)も対象外
  2. 本内容はベストプラクティスを推奨するものではなく、あくまで実験的な観測結果
  3. グローバル規模の社内政治が顧客の意思決定に影響を与える可能性がある

今回ご紹介するPoC*1は、実際の顧客データ、特に特定時点におけるデータを使用して行った実験的な検証です。TPC-H や TPC-DS のような一般的なベンチマーク(外部ブログ)ではなく、実データを用いることで、より現実に近い観察が得られました。

ただし、ここでの結果はベストプラクティスを示すものではなく、あくまで観測的な知見であり、今後の機能改善によって変わる可能性が大いにあります

さらに、どれほど優れた結果が得られたとしても、顧客の意思決定は必ずしも機能評価だけで決まるわけではなく、グローバル規模の社内政治や組織的背景が影響する点も考慮する必要があります。

概要解説

今回 PoC を実施することになった背景には、顧客のデータ基盤が Azure Databricks を中心に構成されているという事情があります。Databricks の Unity Catalog を中心としたアーキテクチャを採用した場合、Databricks 社が推奨する Power BI の利用パターンの一つは、DirectQuery on Databricks SQL です。

一方で、DirectQuery は、DB エンジンのチューニングやクラスタースペックの選定、さらには Import や Direct Lake モードと比べて、より多くの最適化作業が求められるという特性があります。そのため、DirectQuery 利用時のベストプラクティスをどこまで理解・実践できているかによって、クエリパフォーマンスが大きく左右されます。

そこで本 PoC では、同じデータ基盤を前提としながら、DirectQuery on Databricks SQL と Direct Lake のクエリパフォーマンスを比較し、どちらが BI 利用においてより適切な選択肢となるのかを検証することを主な目的としています。

ストレージモードの整理

結果を解説する前に、まず Power BI における代表的なストレージモードについて簡単に整理しておきます。本ブログではこれまでも何度か取り上げていますが、特に Direct Lake は Fabric を活用する上で欠かせない重要な要素となるため、改めて触れておきます。

  • Import モード
    • データを Power BI の列データベース(VertiPaq)に取り込み、高速なクエリ性能を実現するモード
    • 最もパフォーマンスが安定しており、DAX の機能制限もほぼなし。一方で、データ更新が必要となり、大規模データではメモリ使用量や更新時間が課題
  • DirectQuery モード
    • データを Power BI に取り込まず、クエリのたびに外部データベースへ SQL を発行するモード
    • 常に最新データを参照できる点がメリットであるが、クエリ性能はデータベースエンジンやそのチューニング等に大きく依存し、DAX の制約も多く存在する
  • Direct Lake モード
    • DirectQuery と Import の利点を組み合わせた新しいストレージモード
    • OneLake 上の Delta Parquet ファイルを直接読み込み、必要なデータだけをメモリへロードし、VertiPaq エンジンでクエリを実行
    • データコピーを行わずに高いクエリ性能を実現できるため、Fabric を前提とした分析基盤では必ず検討すべき選択肢
  • Dual モード
    • テーブルが状況に応じて Import と DirectQuery のどちらとしても振る舞うモード
    • 主に Composite Model で使用され、ディメンションテーブルを Dual にすることで、DirectQuery 環境でもクエリ性能を改善できるケースがある

Direct Lake モード

当ブログでは、これまでにもストレージモードについて何度か解説してきました。Direct Lake は、DirectQuery と Import モードの両方のメリットを併せ持つストレージモードとして位置づけられており、Microsoft Fabric を活用するうえで、ぜひ押さえておきたい重要な機能の一つです。

概要は上述の通りですが、Direct Lake は DirectQuery の柔軟性Import モードの高いクエリパフォーマンス を継承したモードと言えます。

本件の顧客はデータを Azure Databricks 側に保持しており、OneLake のショートカット経由でセマンティックモデルを構築するパターンを前提に、Direct Lake の活用を検討していました。

このアーキテクチャ選択が本 PoC の重要な前提条件となっているため、次回以降で詳しく解説していきます。

DirectQuery モード

一般的に、DirectQuery は Import / Direct Lake モデルよりも遅いことがよく知られています(世の中にある2,000万個のセマンティックモデルの90%はインポートモデル)。

下図のように、純粋な DirectQuery モデルでは、すべてのテーブルが DirectQuery モードで動作します。

すなわち、Power BI レポート内でビジュアルを操作すると、DAX クエリが発行されます。発行された DAX クエリは Power BI の VertiPaq Storage Engine を経由し、SQLクエリに変換され、データソースへそれを送信して実行結果を待ちます。Power BI のネイティブ言語は DAX で、SQL ではないため、DAXがSQL構文に変換される過程や処理の違いにより、DirectQuery ではどうしてもパフォーマンスに限界が生じます。

Dual モード

一方、下図のように すべてのディメンションテーブルを Dual モードに変更すると、多くの利点が生まれます。Dualモード とは、DAX エンジンが自動的にこのクエリはインポートモードで処理できる、このクエリは DirectQueryで処理したほうがクエリプランが良いなど、臨機応変に最適なパターンを判断できるモードとなります。

例えば、メモリにデータがキャッシュされるので、スライサーやフィルターの表示速度が高速になったり、ディメンションテーブルを使った処理(例:顧客総数を数えるメジャーなど)は Import モードのパフォーマンスで実行されます。これにより、すべてのテーブルを DirectQuery にする場合よりもはるかに効率(クエリプラン)が良くなります。

複合モデル(インポートテーブル ⇔ DirectQuery テーブル同士のリレーションシップ)

先ほどと似ているようで少し違うのが、Dim テーブルを明示的に Import テーブルとして使用ときです。

先程はDual Mode = 臨機応変にエンジンがダイナミックにどちらのモードを使うかを決めてくれるモードでしたが、インポートテーブルと DirectQuery テーブルを同じモデル内で混在させると、クエリパフォーマンスがかなり悪くなることがあります。理由として、インポートと DirectQuery の間のリレーションシップが 「限定(Limited)リレーションシップ / Weak リレーションシップ」 として扱われるためです。

限定リレーションシップは、例えば本来であれば「年」で1回フィルターすれば済む処理が、dim_date テーブルはリレーションシップのカーディナリティ(粒度)でフィルターを作ってしまう=全日付(例:365日)に展開され、その粒度でフィルター処理が行われてしまうため、クエリ速度が大幅に遅くなってしまいます。

集計テーブルを用いた複合モデル (パフォーマンス最適)

一方で、ディメンションテーブルを Dual モードに設定すると、これらの Weak リレーションシップが Regular(強い)リレーションシップ に変更されます。

これを示したのが上図で、fact_sales、fact_agg、dim_dateの3つのテーブルについて考えてみます。

  • fact_sales(DirectQuery)を参照する際:
    dim_date は DirectQuery テーブルとして動作し、最適なクエリプランが使用される
  • fact_agg(Import の集計テーブル)を参照する際:
    同じ dim_date は Import モードとして動作し、パフォーマンスに悪影響を与えない。Dual モードを使うことで、エンジンがクエリ内容に応じて最適な実行パスを自動的に選択し、詳細データでも集計データでもパフォーマンスを向上させることができる

今回の PoC では、集計テーブルは使用していないため、前述した Dual モードを用いたスタースキーマモデルを前提に検証を行っています。
なお、データ量が小さいケースでは、仮にクエリプランが最適でなくても結果としてクエリパフォーマンスが良好に見える場合があります。そのため、実際のパフォーマンスにはデータ量そのものだけでなく、データの分布、セマンティックモデルの複雑性、リレーションシップ設計など、複数の要因が大きく影響する点に注意が必要です。

パフォーマンス比較

モデル・レポートデザイン

ここから、いよいよ本題であるパフォーマンス比較に入ります。比較に使用したセマンティックモデルは、できるだけ条件差を排除するため、シンプルなスタースキーマで設計しています。全体のデザインは以下の構成です。

特に注目すべきは Fact テーブルで、行数は 23 億行、列数は 14 列という大規模データとなっています。Direct Lake モデルでは DirectQuery と完全に同一のスキーマを採用することで、純粋なストレージモード差による性能比較ができるようにしています。

比較するクエリは下記レイアウトのレポートをCluster Bar Chart (ランキングチャート = 積み上げ横棒グラフ)とMatrix (マトリックス) ビジュアルを中心に比較検証をしました。

以下は、パフォーマンス比較に使用した Clustered Bar Chart(ランキングチャート)のクエリです。このクエリを用いて、Direct Lake と DirectQuery の実行時間および挙動をマトリックスビジュアルに対しても同様に、比較検証しました。

DEFINE
--(中略)
    VAR __DS0Core = 
        SUMMARIZECOLUMNS(
            'Table'[項目],
            __DS0FilterTable,
            __DS0FilterTable2,
            __DS0FilterTable3,
            "M1", 'Table'[M1]
        )

EVALUATE
    __DS0Core

データの抽出方法や Direct Lake のキャッシュクリア手順など、テスト実施にあたっての詳細なプロセスについては、機会があれば別途ご紹介したいと思います。本記事では、このようなクエリにおけるパフォーマンス比較結果にフォーカスして解説していきます。

比較結果

以下は、メインとなる2つのチャートのそれぞれの結果です。KPI アイコンは🟢🟡🔴の3色ですが、🟢がベストクラスとなります。

Cluster Bar Chart (ランキングチャート)

Matrix (マトリックステーブル)

結果を吟味する前に、まずは各種用語を確認しておきましょう。

クエリパフォーマンスの結果テーブル
  • Mode
    DQ =Direct Query, DL = Direct Lake
  • PerResult
    DQ と DL において、異なるアーキテクチャで比較したもの。
    • DQ > dbx_ASU:
      Fabric 容量を使用せず、Power BI の A SKU (A4) を使用し、DirectQuery on Databricks SQL のパフォーマンスをテストしたシナリオ。データ量は40億行ですが、参考値として掲載
    • DQ > dbx_FSU:
      今回のベンチマークであるシナリオ。このシナリオの結果を Hot Cache とCold Cache 別に他のシナリオを比較しています
    • DQ > full_lh_FallbackDQ:
      DQ において、Databricks SQL エンジン以外に、Direct Lake を意図的に DirectQuery (DQ) へフォールバック(SQL Analytics Endpoint 必要)させた時のパフォーマンスも参考までに載せています。フォールバックは OneLake 内にある Delta Parquet 書式のテーブルに対して、Fabric SQL エンジンによるDirect Query の結果を表示しています
      ※ DQ へのフォールバックについては、こちら()をご参考
    • DL > full_lakehouse: 
      データを外部(Databricks)から OneLake にロードし、永続化されたパターン
    • DL > lakehouse:
      23億行のテーブルのみが OneLake Delta 書式のテーブルになっており、残りのDimテーブルは全てテーブルショートカットを用いてセマンティックモデルを構築
    • DL > MLV
      Fabric の Spark エンジンによって作られたマテビューテーブル。データのリネージが分かりやすく、OneLake ショートカットテーブルからも構築可能
    • DL > partition_shortcut:
      ADLS Gen2 (Azure Databricks で処理済のデルタテーブル) からショートカットで Lakehouse に作り、SQL Analytics Endpoint に対して、セマンティックモデルを構築。ポイントは、DL シナリオにおいて、本シナリオだけが物理的にデータが OneLake にロードされていないこと
  • Cold Cache vs Hot Cache
    • Cold Cache: 最もパフォーマンスが悪い状態時のパフォーマンス
    • Hot Cache: メモリにデータがページングされた状態でのパフォーマンス。Direct Lake が恩恵を受ける
  • ランク
    • 1 = 最も早い、7 = 最も遅いシナリオ
  • 秒数
    • 対象ビジュアルの更新が終わるまでの総時間(DAX クエリ、DirectQuery クエリ、ビジュアルの表示、その他等の処理を含む)
    • 数値が小さいほど、パフォーマンスが良い
      ※ これらの指標に関する解説ははこちら(
  • dbx_F SKU比
    • DQ > dbx_FSKU シナリオの秒数を100%とした場合、他のシナリオがその何%に相当するかを表示したもの
    • 同じく、数値が小さいほど、パフォーマンスが良い
      例: DL > full_lakehouse vs DQ > dbx_FSKU の Hot Cache の比較
      = 1.8秒 ÷ 16.5秒 = 11% (前者は後者の1/9 の時間しか必要なかった)
  • 速さ
    • 計算式: 1 ÷ dbx_FSKU =  dbx_FSKU の何倍速いかを示したもの
    • 倍数になるため、数値が大きいほどパフォーマンスが良い
      例: DL > full_lakehouse vs DQ > dbx_FSKU の Hot Cache の比較
      DL > full_lakehouse (1.8秒) vs DQ > dbx_FSKU (16.5秒)
      = 16.5 ÷ 1.8 = 9.2倍も速い

ご参考までに、DAX クエリとDirectQuery クエリのみの結果も下記に示しておきます。

今回はビジュアル(ランキングチャート、マトリックステーブル)に紐づいているわけではないので、正確な部分をお伝えすることはできないですが、DirectQuery エンジンの処理結果を見ると、dbx_ASKUとdbx_FSKUの差は Cold / Hot に関わらず、殆ど変わらないことが分かります。

一方、full_lh_FallbackDQ シナリオが早いように感じますが、これは

  • Fabric SQL Engine
  • OneLake 内の Delta Parquet
  • ネットワーク hop が少ない

という 「SQLエンジンとしての有利さ」 を示しているだけで、BIとしての最終体験(DAX+ビジュアル+対話性)とは別問題となります。

Hot vs Cold パフォーマンス比較テーブル
  • 各シナリオの Hot Cache が Cold Cache 状態より何倍速いかを示したもの
パフォーマンスに関する洞察

「DirectQuery と Direct Lake を単純に比較するのはフェアではない」という意見があることは理解していますし、その点について異論はありません。重要なのは、顧客にとって中長期的にスケールメリットがあり、最終的にどの選択肢が最適なのかという視点です。BI 観点で現実的かつ持続可能な選択肢は何かを見極めることが、本 PoC の目的となります。

以下、マトリックステーブルを例に、PoC の結果を解説していきます。

  1. Direct Lake(DL)は Hot Cache 時に圧倒的な性能差を生む
    • Direct Lake は Hot Cache 状態になると、
      👉 DirectQuery(dbx_FSKU)より 8〜9 倍高速
    • 特に full_lakehouse / lakehouse / MLV は最上位の結果
  2. Cold Cache ではアーキテクチャ差がそのまま性能差になる
    • Direct Lake でも 物理配置が悪い構成(partition_shortcut) は最下位
    • 「Direct Lake = 常に速い」わけではない
  3. OneLake に物理ロードされた DL が最も安定して速い
    • full_lakehouse が Cold / Hot 両方で最速 or 準最速
    • 「DL × OneLake 永続化 × 最適化」が最適解
  4. 外部ショートカット(ADLS Gen2)は DL の弱点が顕在化
    • partition_shortcut は Cold Cache で 最遅(53秒)
    • DL であっても 物理的に OneLake に存在しないと不利
  5. DirectQuery on Databricks SQL は安定だがスケールメリットが小さい
    • dbx_FSKU は Cold / Hot の差がほぼ無い(= キャッシュ恩恵が小さい)
    • インタラクティブ BI では伸び代が少ない
    • DQ on DBX SQL は「1クエリ性能」ではなく「同時利用・反復操作」に弱い。今回の観測結果によると、DirectQuery クエリ単体が16秒でも、それが100人×Excel操作で同時に走れば、CPU・コスト・待ち時間が一気に破綻する可能性あり

洞察①: Direct Lake Hot Cache は「別次元」のパフォーマンス

  • full_lakehouse
    • Cold: 15.9秒(1.8x)
    • Hot: 2.9秒(8.9x)
  • lakehouse / MLV も同等レベル

📌 理由

  • Direct Lake は VertiPaq による列指向メモリ処理
  • Hot Cache では Parquet → VertiPaq の再ロード不要
  • DQ のように SQL 実行待ちが発生しない

👉 結論

ビジネスユーザーが繰り返し使うレポートでは
Direct Lake Hot Cache が最強

洞察②: Cold Cache は「設計の良し悪し」がそのまま結果に出る

  • partition_shortcut
    • Cold: 53.1秒(最下位)
  • full_lakehouse

    • Cold: 15.9秒(最上位)

📌 理由

  • Cold Cache 時は:
    • Parquet ファイル数
    • Row Group 数
    • V-Order 有無
    • データ局所性
      そのまま IO + メモリ負荷 になる (詳細は次回以降)

👉 結論

Direct Lake の Cold Cache は「物理データレイアウトのテスト」そのもの

洞察③: OneLake に物理ロードされた DL が最もバランスが良い

  • full_lakehouse は:
    • Cold / Hot ともに上位
    • パフォーマンスのブレが小さい

📌 理由

👉 結論

Fabric に最適化させる余地を与えた構成が勝つ

洞察④: MLV(Materialized Lake View)は非常に優秀な選択肢

  • MLV
    • Cold: 18.5秒
    • Hot: 3.2秒
    • Hot/Cold 改善倍率:5.8x〜6.7x

📌 理由

  • Spark による事前集約・整理
  • OneLake 永続化
  • リネージ / 管理性も高い

👉 結論

「外部データ × Direct Lake」なら MLV は最有力

洞察⑤: DirectQuery on DBX SQL は「悪くないが伸びない」

  • dbx_FSKU
    • Cold: 28.6秒
    • Hot: 26.1秒
    • 改善倍率:1.1x

📌 理由

  • キャッシュは DBX 側に依存
  • Power BI 側のキャッシュ恩恵が殆どない
  • クエリごとに SQL 実行が必要

👉 結論

DQ は リアルタイム性・統制 には強いが、インタラクティブ BI の伸び代は限定的

技術的結論と意思決定情の示唆

以下、技術的及び意思決定上の観点から見た結論となります。

  • Direct Lake はアーキテクチャ次第で圧倒的に強い
  •  特に:
    • OneLake 永続化
    • V-Order / Compaction
    • 適切なパーティションが揃った時の Hot Cache は別次元
  • 意思決定上の示唆
    • 「DirectQuery vs Direct Lake」ではなく
      👉 「どの物理配置で、どの運用を想定するか」
    • 中長期・全社 BI・ビジネスユーザー活用では
      👉 Direct Lake が明確に有利
追加考察

PoC を開始する前に、顧客ニーズの1つが下記のものでした。

本社がデータを一元管理し、標準化されたダッシュボードを提供しつつ、各支社(ビジネス側)はそれを活用・拡張分析できる形を目指しています

この中で、「Excel で分析」利用を前提とした議論があり、仮に DirectQuery (DQ) on Databricks SQL を選択した場合のリスクについて言及しておきます。

1. 「Excel で分析」× DQ on Databricks SQL は CPU 負荷が急増しやすい

当該企業では、Power BI レポートだけでなく、セマンティックモデルに対する「Excel で分析(Analyze in Excel)」の利用も想定されています。

Excel からの接続は、

  • ピボット操作
  • 行・列の展開
  • フィルターやスライサー操作
    などにより、短時間に大量のクエリが発生しやすいという特性があります。

DQ on Databricks SQL の場合、これらの操作がすべて Databricks SQL Warehouse へのクエリとして実行されるため、CPU 使用率が急激に上昇するリスクがあります。

2. DQ on Databricks SQL は「ユーザー増加=リニアにコスト増」になりやすい

DQ on Databricks SQL では、

  • クエリ = Databricks SQL Warehouse の CPU 消費
  • ユーザー数・Excel 利用者数が増えるほど、CPU とコストが比例して増加

特に Excel 利用は、

  • Power BI レポートよりも
  • クエリ数・粒度・自由度が高くなりがち

その結果、

  • ピーク時の CPU スパイク
  • Warehouse サイズ拡張 or 同時実行数制限
  • 想定外のコスト増
    につながる可能性があります。

👉 この点で、DQ on Databricks SQL はスケールメリットに乏しいという懸念が明確になります。

3. Direct Lake は Excel 利用時もスケールしやすい

一方、Direct Lake の場合:

  • クエリは Fabric 容量(VertiPaq エンジン)側で処理
  • Databricks SQL Warehouse の CPU を消費しない
  • Excel からの分析においても、Hot Cache が効いた状態では、非常に高速かつ安定したレスポンスを維持
  • ユーザー数・Excel 利用者が増えても、Fabric 容量のスケールで吸収可能

👉 BI 利用が全社・支社へ広がる前提では、Direct Lake の方が中長期的なスケールメリットが大きい。

4. PoC 結果 × Excel 利用前提での総合的な示唆

本 PoC の数値結果からも明らかなように:

  • Direct Lake(特に full_lakehouse / MLV)は Hot Cache 時に DQ on Databricks SQL の 6~9 倍以上の性能

これに加えて、

  • Excel 利用によるクエリ増加
  • CPU 使用率・コスト増リスク
    を考慮すると、

👉 「Power BI + Excel でビジネスユーザーを広く Enable する」という目的に対しては、DQ on Databricks SQL は構造的に不利であり、Direct Lake の方が適している
という結論がより強く裏付けられます。

まとめ

結論として、純粋に技術的・物理的なパフォーマンス観点に限って言えば、今回の PoC では Direct Lake に優位性がある結果となりました。ただし、冒頭でも触れた通り、最終的な意思決定を行うのは顧客自身であり、その判断は単なる性能比較だけでなく、グローバル全体のデータ戦略や既存基盤との整合性を踏まえたものである必要があります。

Microsoft としては Direct Lake を推奨する立場ではありますが、特にグローバル企業においては、各リージョンや部門単位の最適解ではなく、全社的なデータ戦略に沿った選択であるかどうかが、より重要な判断軸となります。

次回は、今回の PoC を通じて直面した技術的なブロッカーや得られた学びを整理するとともに、性能やアーキテクチャ以外にも考慮すべきポイントについて共有していきたいと思います。

*1:Proof of Concept、顧客が特定の技術やアーキテクチャを採用する前にその実効性の「確からしさ」を理解するための実証実験