前回のブログでは、Azure Databricks を中心としたデータ基盤において、DirectQuery (DQ) on Databricks SQL と Direct Lake を比較した PoC の背景と、パフォーマンス結果の全体像をご紹介しました。
本稿ではその続編として、より技術的に踏み込み、Mirrored Unity Catalog(UC)から Direct Lake を構築した場合に直面する落とし穴を中心に解説していきます。
特に、ミラーリングはリアルタイム同期に優れる一方で、Direct Lake が求める分析向けデータレイアウトとは必ずしも相性が良くない点が、今回の PoC を通じて明確になりました。また、ADLS Gen2 ショートカットを用いた Direct Lake と、OneLake にデータを永続化した Direct Lake(Lakehouse における Fully Materialized Delta tables)では、パフォーマンス特性や運用上のメリット・デメリットが大きく異なります。
第2回では、これらの違いを整理しながら、なぜ Direct Lake の性能がアーキテクチャ次第で大きく変わるのか、そして Fabric を前提とした最適な設計とは何かについて、PoC で得られた学びをもとに考察していきます。
ミラーリング
Power BI は Microsoft Fabric を構成するワークロードの一つであり、今後 Power BI を語るうえでは、常に Fabric を前提として捉えることが将来像となります。一方で、Power BI は誕生から約 10 年間、Fabric とは独立したデータ分析基盤として進化してきた背景もあり、可視化や分析といった Power BI 単体のニーズに焦点を当てる場合には、Fabric を切り離して語られることもあります。
しかし、今回取り上げる事例では Fabric の存在が前提となっており、アーキテクチャ設計の観点からも、PoC の段階で Mirrored Unity Catalog を活用することを検証スコープに含めています。そのため、本章ではまず前提知識として、Fabric におけるミラーリングの考え方について簡単に触れておきたいと思います。
① DB (データベース) ミラーリング(従来型)
DB ミラーリングとは、データそのものを Near Real-time で複製する方式です。
元のデータベースで発生した変更を、ほぼリアルタイムで別のデータベースにコピーします。コピー先にも同じデータが物理的に存在するため、即座に利用できますが、データの二重管理によるストレージコスト(現時点、Fabric のSKU サイズによって無料ミラーリングストレージ (TB換算) が異なる)や同期負荷が発生します。
② メタデータミラーリング(Databricks Unity Catalog Mirroring)
データ本体ではなく、テーブル定義やスキーマ、権限といったメタデータを同期する方式です。
Databricks Unity Catalog の構造を Fabric 側に反映できるため、ガバナンスや管理の観点では非常に有効です。この方式でのミラーリングはメタデータのみを同期し、OneLake ショートカットを使ってデータにアクセスします。
一方で、データの物理レイアウト(ファイルサイズや並び方)は最適化されないため、分析用途、特に Direct Lake ではパフォーマンス面で注意が必要になります(本記事のメイントピック)。
③ オープンミラーリング(Open Mirroring)
外部アプリケーションやパートナー製品が変更データを Fabric に直接書き込み、Fabric のミラーリングエンジンが OneLake へ継続レプリケーションする仕組みです。
アプリ側は CDC(変更データ)を所定の形式で Landing Zone に書き込むだけで、差分処理や Delta Parquet への変換、OneLake への反映は Fabric が担います。
「Open」とは、特定ベンダー専用ではなく、任意のアプリが拡張的に連携できる点を意味します。Fabric 側ではミラー済みデータが読み取り専用で管理され、BI・AI・分析など複数のワークロードから横断的に活用できます。
ミラーリングの利点
以下は、ミラーリングの利点となります。
- 複雑なデータパイプラインは不要で、データは自動的に OneLake へ複製
- データは Delta Parquet 形式で保存される (オープンで分析に最適)
- Power BI、Spark、その他の Fabric ツールをミラーリングされたデータに直接利用
なお、全ての機能は必ずFabric容量が必要であり、Power BI Pro/PPU ライセンスだけで運用する場合、上記いずれのミラーリングも使用することはできません。
各種テストパターンの解説
ここからは、前回紹介した各種テストパターンにおける長所と短所を紹介していきます。
DirectQuery on Databricks SQL Warehouse
対象パターン
- dbx_ASKU
- dbx_FSKU
- full_lh_FallbackDQ (Databricks SQL ではなく、Fabric SQL による処理のため)

長所
- リアルタイムアクセス
- データの重複なし
- Databricks SQL Warehouseでスケール
短所
- クエリ性能の低下
- 最適化に多くの工数が必要で
- DAX 関数の制限
- コストの高さ (消費CUが上昇)
DirectQuery on Databricks SQL には、データコピー不要でリアルタイムにアクセスでき、Databricks SQL Warehouse のスケールをそのまま活用できるという大きなメリットがあります。
しかし、いくつか重要なトレードオフもあります。 パフォーマンスは Import や Direct Lake より遅く、チューニングや最適化の作業が多く必要になります。また、多くの DAX 関数が DirectQuery では動作しないという制限もあります。
さらに、分析レポートを実行すると、そのたびに SQL Warehouse へのクエリ実行が発生するため、コストが高くなりがちです。データをメモリにページングしないため、Fabric CU (CPU) 消費も高くなる傾向があります。 そのため、当該パターンはリアルタイム性や中央集権的なガバナンスには優れていますが、顧客が求めている「Power BI や Excel を使ったビジネスユーザー中心の高速インタラクティブ分析」にはあまり向いていません。
Direct Lake with OneLake Shortcut
対象パターン
- partition_shortcut

長所
- データの重複なし
- 即時入手可能
- より多くのデータソースを導入する柔軟性
- 低運用オーバーヘッド
- クロスエンジンデータ共有に有用
短所
- ADLSにおける Parquet ファイルのレイアウトに依存するパフォーマンス
- Fabricネイティブの最適化が少ない
- Direct Lake におけるメモリプレッシャー
- インクリメンタル・フレーミングの効率に影響を及ぼす可能性
少し技術的な話になりますが、ADLS Gen2 への外部ショートカットを通して Direct Lake セマンティックモデルを構築する場合、Lakehouse は既存の Delta Parquet ファイルを OneLake にデータを物理的に取り込むことなく、SQL Analytics Endpoint (SEP) を通じて公開されます。
このデザインパターンにはいくつかの利点があります。
- データの重複を避けられ、ストレージコストを低く保てるほか、Databricks を中央的なデータプラットフォームとして位置付ける顧客が、その ETL パイプラインを活用できるため、アーキテクチャを変更する必要がない
- 👉 Fabric を純粋に消費層・BI 層として使いたいと考えているユーザーにとっては、このアーキテクチャは「適している」と見ることが可能
重要な考慮点
Direct Lake のパフォーマンスは ADLS 内の Parquet ファイルのレイアウトに完全に依存するようになります。もしデータセット(Databricks側で作られた Delta テーブル)に小さなファイルが多数含まれていたり、パーティション*1が多過ぎたり、V-Order や適切な row group の配置で最適化されていない場合、コールドクエリ*2のパフォーマンスは大きく低下してしまいます。
また、今回のような 23 億行の大規模データセットでは、ソースデータが適切にパーティション化または再配置されていない限り、Direct Lake はメモリプレッシャーに直面する可能性があります。実際、当該顧客に対して以前実施した PoC ではこの問題に遭遇したため、日付列に対してパーティションを実施してパフォーマンスを改善しました。
さらに、Fabric は外部ファイルを Fabric 内のデータほど最適化できないため、Delta Log の履歴や Deletion Vector の問題がある場合、incremental framing (Fabric 製品チームによる解説①、②) の効率も低下します。
まとめますと、当該デザインパターンは柔軟性とゼロコピーアクセスを提供しますが、大規模 Direct Lake シナリオではパフォーマンスと運用上のトレードオフを十分理解しておく必要があり、PoC の結果を見てもCold Cache の状態ではパフォーマンスが悪かったことが伺えます。
Direct Lake with Mirrored Unity Catalog (UC)
対象パターン
- なし💡(詳細は後述)

長所
- Fabric とのシームレスな統合
- 自動同期とスケーラビリテ
- Databricks 環境に慣れたユーザーにとっては快適な体験
短所
- 💡読取専用
- ⚠️リソース消費 (Power BIの視点)
- 💡V2 チェックポイントの問題
- ⚠️安定性
こちら、当記事のメイントピックとなりますが、上図のように、Azure Databricks Mirrored UCを使用し、Direct Lake on SQL Analytics Endpoint を作った場合、クエリ時にDirect Lake がメモリ不足を引き起こし、結果を得ることが出来ませんでした。
👉 結論
23億行のシンプルなスタースキーマであっても、
このデザインパターンは機能しなかった
留意したいことは、
- PoC のデータ量が23億行もあったこと
- 小さいデータセットでは異なる結果になる可能性がある
ということです。
Mirrored UC のよい点として、UC の構造が自動ミラーリングされ、Fabric 内でネイティブ操作可能であり、シームレスな体験を得ることができることです。自動でSQL Analytics Endpoint が作られ、Direct Lake セマンティックモデルをすぐに作ることができます。
自動同期及びスケーラビリティにも優れ、スキーマ管理が楽になります。つまり、テーブルがDatabricks 側で追加されれば、Mirrored UC 側にも自動的に反映されることになります。先程解説した ADLS Gen2 ショートカットのパターンと同様、Lakehouse や AI ツールとも連携ができるようになります。
利用制限の詳細
しかし、PoCの実施で判明したのは、様々な不利な状況があることでした。まず、UC をベースとした管理になるため、Fabric 側から Write (書き込み) 操作を行うことが許可されず、Read-only のため、外部ショートカットシナリオのように、V-orderといった Write 処理を実行することができません。
次に、特にデータ量が多い場合、リソース消費が非常に高くなります。その意味で、外部ショートカットシナリオに類似しますが、V-orderができない分、データ量と相談して、構成を慎重に検討する必要が出てきます。
Databricks では現在、”DirectQuery フレンドリー”な Liquid Clustering (AI による Dynamic Clustering) を使っており、PoC 当初、これをDatabricks 側で有効にすれば、Direct Lake のパフォーマンスにもプラスになるのではないかと考えていました。しかし、検証を進めていくと、我々が想定していなかった問題が複数起こり、デザインパターンの見直しが必要となりました。
リソース消費の問題
当該シナリオのおさらいです。
- データ量: 23億行
- Fabric SKU: F128
DirectQuery へのフォールバックを回避するため、 F128 が必須 - Mirrored UC で作成された Direct Lake モデル (DL on SQL) に対するDAXクエリの実行
Direct Lakeのパフォーマンスを実施する前提として、Direct Lakeの制限をまず知る必要があります。顧客のデータ量は23億行であり、Fabric は Fabric 容量の SKU 別にDirect Lake のクエリパフォーマンスをキープするための制限*3を設けており、下図がこれを示したものです。

Direct Lake overview - Microsoft Fabric | Microsoft Learn
今回の 23億行という制限は、ちょうど 「Rows per table (millions)」の列に相当するもので、F128 が1つのテーブルで30億行まで許容されます。この SKU サイズであれば、このような粒度の細かいデータを Direct Lake モデルで分析ができるようになるということです。
この前提を基に、下図にある構成、つまりMirrored UC で自動的に作成されたSQL Endpoint に対して、Direct Lake セマンティックモデルが作られ、それを基にしたPower BI レポートのクエリパフォーマンスを測ってみました。

👉 結果
表示不可

この図は PoC でパフォーマンス測定に使用したレポートとなります。ご覧の通り、スライサーを除く、全てのビジュアルでエラーが発生しました。最も処理が軽いカードビジュアルであっても、エラーを起こしています。
この問題を調べるため、3行だけを返すクエリをパフォーマンス測定ツールの DAX Studio に記述して実行してみたところ、以下のような結果となりました。
リソース管理: メモリ不足のため、要求された操作は完了できません。 消費メモリ: 76,866 MB、メモリ制限: 51,200 MB
インメモリデータの量を制限してデータセットのサイズを縮小するか、十分なメモリを持つ Fabric または Premium 容量でホストしてください
Power BIで大量のデータを処理したことがある人はお分かりだと思いますが、このような3行だけを返すもので、メモリーエラーになるケースはかなり稀であると言えます。
なぜ、3行だけを返すのに、これほどのメモリ使用量になったのでしょうか?それは、Direct Lake の特徴及びその他の要因がお互い絡んでいることが要因となっているからです。
Direct Lake クエリのパフォーマンスを理解する
Power BI Direct Lake は新しテクノロジーですが、パフォーマンスを維持するためのシンプルなTipsがいくつかあります。前述の通り、V-order最適化、parquetファイル数を少なくする、そして、parquet 内での大規模な row groups (行グループ) も影響をしています。
これらの基礎に加え、Direct Lakeのキャッシュ運用を理解することが最適なレポートパフォーマンスに繋がります。Delta ファイルの品質については常にトレードオフが存在します。Direct Lake は、サイズの大きい Parquet ファイルや、Z-order (Liquid Clustering) によって最適化されたレイアウトを強く好みます。これは Fabric Warehouse や Databricks SQL の 読み取り専用シナリオでも同様にメリットがあります。

Understand Direct Lake query performance - Microsoft Fabric | Microsoft Learn
詳細は省きますが、Power BI の Analysis Services チームによると、
Direct Lake は大きな列セグメントを好むため、Direct Lakeで大規模なデータセットの列セグメントを作成する際、行グループサイズは800万~1,600万行の範囲を目指すことが推奨される
ということです。下記参考先では100~1,600万行と言及されていますが、今回のように23億行のようなデータセットの場合、800~1,600百万行が良い目安となります。
参考先
Delta Parquet テーブルのレイアウトの違い
前述の通り、Mirrored UC 経由で作成された SQL Analytics Endpoint 上のテーブルを基に Direct Lake セマンティックモデルを構築したところ、今回のデータセットではメモリ不足エラーが発生しました。冒頭でも解説したように、Mirrored UC はメタデータをミラーリングする仕組みであり、実際のデータへのアクセスは Databricks 側のストレージ構成を前提としたものになります。
今回セマンティックモデルに使用した 23 億行の Fact テーブルは、Mirrored UC アイテムとして Fabric 側にショートカット経由で取り込まれています。このテーブルに対して Direct Lake モデルを作成しましたが、メモリエラーが発生したのはこのモデルです。確認すると、Parquet ファイルは約 100 個存在し、1 ファイルあたり約 40MB という比較的小さなサイズになっていました。
前述のドキュメントでも触れた通り、Direct Lake の観点では、Parquet ファイル数は可能な限り少なく、1 ファイルあたり 800~1,600万行程度を目安にすることが推奨されています。今回の構成はそれに比べるとファイル数が多く、サイズも小さいため、Direct Lake にとっては必ずしも最適とは言えないレイアウトでした。また、Mirrored UC が読取専用であることから、Fabric 側から V-order 最適化を実施することもできず、こちらもパフォーマンスを悪化させ、メモリプレッシャーを高める要因となっています。
では、なぜ Databricks 側ではこのような比較的小さなファイルが複数生成されているのでしょうか。Databricks は一般的に DirectQuery を前提とした利用が多く、クエリ処理では大規模なスケールアウト構成を取ることが想定されます。そのため、複数ノードで並列書き込みを行う結果、小さなファイルが多数生成される可能性があります。また、Databricks SQL エンジンは Parquet や Row Group の統計情報を効率的に活用し、不要な読み込みを極力排除する最適化が行われていることも考えられます。
なお、Databricks MVP の Liping Huang 氏(動画11:34~)によれば、ストレージ層(Delta Lake)のファイルレイアウト最適化は非常に重要であり、Apache Spark が高いパフォーマンスを発揮しやすいサイズは約 128MB/ファイルであるとされています。DirectQuery も同様のサイズを好むと推測されますが、今回の実データでは 40MB 前後のファイル構成となっており、この点が Direct Lake のパフォーマンスやメモリ消費に影響を与えたと考えられます。
先ほどのケースとは異なり、今回は Fabric の Spark Notebook を使用し、Mirrored UC を経由してデータを実際に OneLake へ物理的にロードしたパターンです。
小さなファイルを結合して大きなファイルへまとめるコンパクションと、V-Order 最適化が自動的に適用された結果、Parquet ファイル数は元の約 1/7 にあたる 13 個まで削減され、各ファイルのサイズは約 400MB になりました。
このレイアウトは、Direct Lake が最も好む構造に近い状態です。具体的には、
- より大きな Row Group(行グループ)
- 列セグメント数の削減
- 1 セグメントあたりの行数の増加
といった特性を持ちます。
その結果、VertiPaq による辞書変換(transcoding)が大幅に高速化され、Direct Lake のパフォーマンスは向上し、メモリ消費も劇的に低減されました。
辞書(Dictionary)はPower BI Vertipaq エンジンのインポートモデルで使用される圧縮技術であり、Direct Lake の場合、
- データは Parquet(Delta)形式のまま
- クエリ時に必要な列だけを読み込む
- その際に VertiPaq 用の辞書へ変換(transcoding)する
という流れになります。Parquet には Row Group(行グループ)という単位があり、Row Group ごとにローカル辞書が存在します。Direct Lake は最終的に
全 Row Group のローカル辞書を統合して
1つの「グローバル辞書」を作らなければならない
ため、Row Group が多いと:
- マージする辞書が増える
- メモリ確保が増える
- CPU 処理時間が増える
- Transcoding が長くなる
という状態に陥り、結果としてパフォーマンスやメモリ効率に悪影響を及ぼします。
今回のテストから明らかになったのは、単にデータを Databricks 側に保持するかどうかではなく、Direct Lake に適した物理ファイルレイアウトであること、適切に圧縮・最適化されていること、そしてデータが OneLake 内に永続化されていることが、最も高いパフォーマンスにつながるという点です。
特に Hot Cache の状態では、ビジュアルは 3 秒程度で応答しており、23 億行という大規模データであることを考慮しても、クエリパフォーマンスは非常に優れていることが確認できました。
v2 Checkpointによる影響
ここからは Databricks の v2 Checkpoint について少しお話します。v2 Checkpoint*4 とは、大規模テーブルや Liquid Clustering ワークロード向けに Delta Lake のパフォーマンスとスケーラビリティを向上させるために、Databricks が導入した新しい高度なチェックポイント形式です。
Databricks 側で Liquid Clustering を有効化すると、その Delta テーブルでは自動的に v2 Checkpoint が適用されます。 そして PoC 時点の仕様では、v2 Checkpoint を使用している Delta テーブルは、Fabric が Direct Lake セマンティックモデルを処理・更新できない制限の対象になります。
言い換えると、Liquid Clustering を有効にした時点で v2 Checkpoint が自動的に適用され、そのテーブルは Direct Lake の更新が不可能になります。つまり、Direct Lake セマンティックモデルが新しいデータを取り込めなくなるということです。この問題については 製品チームも認識しており、現在対応が進められている段階です。
考察まとめ
Mirroring に関するPoCから得られた重要な教訓のひとつは、Mirroring は分析用途ではなく、あくまで“ほぼリアルタイム同期”を目的として設計されているということです。 Mirroring は、変更検知とメタデータ更新を高速に行うことに特化しており、BI 向けに最適化されたファイルレイアウトを生成するものではありません。
その結果、Databricks から OneLake へ Delta ファイルがミラーリングされる際、ファイルは Databricks に存在する“そのままの状態”でコピーされます。 つまり、V-Order なし、コンパクションなし、何千もの row group、最適化されていないクラスタリング、小さな Parquet ファイルが大量に存在する、といった状況です。
これが直接、次の問題につながります。すなわち、Direct Lake は物理データレイアウトに非常に敏感であるという点です。 たとえレポート上の結果が 3 行しか返らなくても、Direct Lake は裏側ですべての必要なカラムセグメントをロード(hydrate)する必要があります。 もしそれらのセグメントが断片化していたり、高カーディナリティであったり、小さなファイルに散らばっていたりすると、Direct Lake はわずかなクエリ結果を返すために大量のデータをメモリに読み込まなければならず、それが深刻なメモリ負荷やパフォーマンス低下を引き起こします。
ただし、この議論はデータ量やデータの分布、さらにはモデル設計によって結果が左右される点に留意する必要があります。実際には、構築したセマンティックモデル上で DAX クエリのパフォーマンスを実測し、その結果に基づいて判断することが推奨されます。
最終推奨アーキテクチャ
最高のパフォーマンスと長期的なスケーラビリティを実現するためには、データ量を見極めつつ、テストをしてFabric の最適化エンジンが十分に機能できるようにすることが最も重要です。
- Fabric の最適化エンジンが最大限に機能する
- 留意点として、Databricks のデータを OneLake に慎重に取り込む
- 長期的に Fabric を最大活用できるアーキテクチャを設計

今回のデータ量(23億行)では、Direct Lake モデルをMirrored UC テーブル (SQL Analytics Endpoint 経由) の上に直接構築するのではなく、上図のデザインにするこたが最適でした。つまり、Databricks のデータを OneLake に取り込み、Fabric が V-Order、コンパクション、適切な Row Group の配置といった最適化を適用できる キュレーション済み Delta テーブル として保持する必要がありました。これが Direct Lake にとって最適なファイルレイアウトを作り出してくれます。
なお、Databricks から OneLake にデータを取り込む際には、インジェスト(データロード)性能にも細心の注意を払う必要があります。インジェストは、Direct Lake が苦手とする小さなファイルを大量生成しないよう、大きくコンパクトな Parquet ファイルを出力する Spark ジョブによって制御された形で行うべきです (通常、ここはFabric Spark Engineが自動的に処理をしてくれます。
特筆すべき点として、Databricks 側のデータはインジェスト前からすでに Delta Parquet 形式で保持されていたため、23 億行のデータ移行は約 400 万行/秒というスケールで実行できました。実質的にはコピー処理に近い作業となりますが、Spark エンジンが複数ノードにわたって並列処理を行った結果、高速なインジェストが実現できたことになります。
「データを OneLake に持ってきたくない」という声を耳にすることも少なくありません。しかし実際には、データ量や更新頻度、エンドユーザーの利便性、そして中長期的なスケーラビリティを総合的に考慮したうえで、データをどこに配置するのが最適かを判断すべきでしょう。
今回は Direct Lake と DirectQuery on Databricks SQL の比較について、ごく一部の検証結果をご紹介しましたが、Databricks と Power BI を組み合わせて活用されている方々にとって、何らかの示唆となれば幸いです。