この記事では、ありがちな原因を「切り分け → 直し方」の順で、DB側・モデル設計・可視化の3方向から整理します。全部やる必要はなく、ボトルネックになっている場所から順に当てていくのが最短です。
DirectQueryが遅くなりやすい典型パターン
DirectQueryの遅さは、次のような構造で起きがちです。
1回の操作で複数クエリが飛ぶ
これだけでクエリ本数が増えます。クエリが軽くても本数が多いと遅く感じます。
「DBが重い」ではなく「DBに重いSQLを投げている」
DirectQueryはDAXやビジュアルの要求がSQL等に翻訳されます。モデル設計やメジャーが複雑だと、DBが不得意な形のSQLになり、実行計画が崩れて急に遅くなることがあります。
スライサーやフィルター自体が重い
高カーディナリティ(値の種類が多い)列をスライサーに置くと、選択肢の取得だけで時間がかかります。ユーザーは「スライサーを開くのが遅い」「クリックのたびに固まる」と感じます。
明細を見せるページがとくに危険
テーブル(明細)を大きく表示したり、多数列を並べたり、並べ替えや検索を多用すると、DBへの要求も描画負荷も上がります。
結論として、まずは「クエリが遅い」のか「クエリは速いが本数が多い」のか「描画が重い」のかを分けるのが重要です。
まずやる切り分け:どこが遅いのかを特定する
改善は“犯人探し”が9割です。次の順で見ていくと迷いにくいです。
(1) どの操作が遅いかを言語化する
(2) Power BI側で、遅いビジュアルを特定する
Power BI Desktopのパフォーマンス計測(パフォーマンス アナライザー等)で、どのビジュアルが何秒かかっているかを見ます。
ここで大事なのは次の見分けです。
-
遅いのが1つのビジュアルなのか
-
全部そこそこ遅いのか
-
クエリ待ちなのか描画待ちなのか
(3) DB側で、実際に飛んでいるクエリを捕まえる
DBのクエリ履歴・実行計画・待機イベント(ロック、I/O、CPU)を確認します。
DirectQueryが遅いとき、DBのメトリクスは大きく3タイプに分かれます。
-
CPUが張り付く:集計のやり方、結合、GROUP BY、DISTINCT系が重い
-
I/Oが重い:スキャンが多い、インデックス不足、パーティションが効いていない
-
待機(ロック/同時実行)が多い:更新処理との競合、リソース不足、キュー待ち
(4) ネットワーク/ゲートウェイ由来かを疑う
オンプレ接続や別リージョンのDBだと、クエリ自体は速いのに往復遅延で体感が悪くなります。
「DBの実行時間は短いのにPower BIでは長い」場合、ここが犯人になりやすいです。
ここまでで、主犯が「DB」「モデル」「可視化」「ネットワーク/ゲートウェイ」のどこかに寄ります。次章からはそれぞれの改善策です。
DB側の改善:DirectQueryで一番効きやすいところ
DB側は、同じデータ量でも設計次第で桁違いに変わります。DirectQueryは“都度クエリ”なので、1回のクエリを50ms削るだけでも体感が大きく改善します。
3-1. フィルター・結合・集計に効くインデックス設計
DirectQueryのクエリはだいたい次の要素を含みます。
-
期間フィルター(Date)
-
ディメンションの選択(商品、部門、地域など)
-
ファクトとディメンションの結合
-
集計(SUM/COUNT/DISTINCTなど)
対策の方向性:
-
結合キーに適切なインデックス(できれば整数のサロゲートキー)
-
よく使うフィルター列(特に日付、状態フラグ、カテゴリ)にインデックス
-
集計で参照される列を含めたカバリング(DBの方式に合わせる)
-
統計情報を最新に保つ(実行計画がブレる原因を減らす)
「日付で絞るのに全表スキャンしている」「結合の順番が悪い」「DISTINCTが暴れている」などが見えたら、インデックスと統計が第一候補です。
3-2. “見た目は便利”なビューの積み重ねを避ける
DirectQueryでよくある失速要因が、ビューの多段化です。
ビューAがビューBを参照し、さらにその上にビューC…のように積むと、最終的に生成されるSQLが巨大化し、最適化が効きづらくなります。
対策:
-
Power BI向けに、シンプルな形の提供レイヤーを用意する(必要なら専用テーブル/マテビュー)
-
スカラー関数や行単位処理(行ごとの変換)が混ざる設計を避ける
-
結合や計算は「どこでやるか」を固定する(DBでやるならDBで完結)
3-3. 集計を前に寄せる:マテビュー・集計テーブル・スナップショット
DirectQueryで重いのは「巨大ファクトを毎回集計」するケースです。
この場合、最も効くのは“集計済みを持つ”ことです。
対策例:
Power BI側の集計機能(後述)と組み合わせると、普段の閲覧は集計済みに当たり、明細が必要なときだけ詳細へ、という設計ができます。
3-4. 同時実行とリソース:遅いのではなく“混んでいる”
同じレポートでも、午前中だけ遅い、月末だけ遅い、という場合は同時実行が濃厚です。
DirectQueryは閲覧者が増えるほどDBの負荷が直線的に増えやすいです。
対策:
3-5. ゲートウェイとネットワーク:往復遅延と詰まりを減らす
オンプレや閉域網の場合、ゲートウェイ経由の遅延が効いてきます。
対策:
-
ゲートウェイをDBに近い場所へ置く(ネットワーク距離を縮める)
-
ゲートウェイマシンのCPU/メモリ/帯域を確保する
-
同時接続が多いなら冗長化やクラスター構成を検討する
-
不要な再接続が起きないように認証方式やタイムアウト設定を確認する
「DBは速いのに遅い」問題がここで解決することは珍しくありません。
モデル設計の改善:DBに優しい形に整える
DirectQueryはモデルがそのままクエリ形状に反映されます。モデルが整うと、DBへのSQLも素直になります。
4-1. スター型(ファクト+ディメンション)を基本にする
DirectQueryでは特に効きます。
基本:
避けたい設計:
-
多対多が多い
-
双方向フィルターだらけ
-
正規化しすぎて結合が多段になる
-
ファクト同士を直接つなぐ
どうしても多対多が必要なら、ブリッジテーブルで設計を固定し、フィルター伝播が予期せず広がらないようにします。
4-2. キーと列を見直す:文字列キーは重くなりやすい
DirectQueryの結合は頻繁に走ります。結合キーの型が重いと、その分だけ遅くなりがちです。
対策:
-
可能なら整数のサロゲートキーを使う
-
キー列やフィルター列のデータ型を最適化する(不要に大きい型を避ける)
-
モデルに取り込む列を最小限にする(使わない列は削除)
-
高カーディナリティ列(IDや自由入力文字列)を安易にスライサーに置かない
4-3. リレーション設定でクエリが激変するポイント
考え方:
4-4. 集計(Aggregations)と複合モデルで“普段は速く”する
DirectQueryをやめずに体感を上げる強力手段が、集計テーブルの活用です。
考え方:
-
よく見る粒度(例:日×店舗×商品カテゴリ)で集計済みテーブルを用意
-
Power BI側で集計テーブルを優先して使うように設定
-
明細が必要なときだけ、詳細(DirectQueryのファクト)へフォールバック
さらに、ディメンションのような小さい表はImportにして、ファクトだけDirectQueryにする(複合モデル)と、フィルター操作が軽くなることがあります。
「全部DirectQuery」にこだわるより、“ユーザーが触るところ”だけでもImportで支えると効きます。
4-5. メジャー(DAX)の作り方で、SQLが重くなる
DirectQueryでは、DAXがDBクエリに落ちます。重くなりがちなのは次です。
対策の方向性:
-
まずは単純な集計(SUM, COUNT, AVERAGE)中心に寄せる
-
反復が必要な計算は、可能ならDB側で前計算(列や集計)
-
メジャー内は変数を使って同じ式を再計算しない
-
DISTINCTCOUNTが必要なら、要件が許す範囲で近似や集計済みを検討
-
明細に近い粒度で複雑な計算を避け、粒度を上げてから計算する
4-6. 日付の扱いを整える
日付はほぼ確実にフィルターに使われるので、ここが崩れると全体が遅くなります。
-
専用の日付テーブルを用意し、正しいリレーションでつなぐ
-
不要な自動日付(隠し日付テーブル)が増えないように設定を見直す
-
期間フィルターが効く設計(パーティションやクラスタリングと整合)にする
4-7. RLS(行レベルセキュリティ)がある場合の注意
RLSは便利ですが、DirectQueryではクエリ条件が常に追加されます。設計が悪いと劇的に遅くなります。
対策:
可視化の改善:クエリ本数と“重い見せ方”を減らす
同じモデルでも、レポートの作り方で体感は大きく変わります。DirectQueryでは「クエリを減らす」「結果セットを小さくする」が基本です。
5-1. 1ページのビジュアル数を減らす
ビジュアルは「1つ=1クエリ」が基本です。ページに10個あれば、操作のたびに10個分更新されがちです。
コツ:
5-2. 相互作用(クロスフィルター/ハイライト)を整理する
便利だから全部オン、はDirectQueryだと負担が大きいです。
5-3. スライサーは“軽い列”を選ぶ
スライサーは「選択肢の取得」と「選択時の再クエリ」の両方が発生します。
避けたい例:
工夫:
-
カテゴリ階層(大分類→中分類→小分類)で絞り込ませる
-
検索ボックス前提の設計にし、候補全件を毎回描画しない
-
期間スライサーはできるだけシンプルに(相対日付なども使いどころを選ぶ)
5-4. 明細テーブルの出し方を変えるだけで速くなる
DirectQueryで「表」を大きく出すのは最も重い部類です。
改善の方向性:
5-5. “クエリ削減”の発想で操作回数を減らす
スライサーを触るたびに即クエリを飛ばすのではなく、まとめて反映する設計にすると体感が安定します。
例:
進め方のおすすめ:最短で効かせるチェックリスト
迷ったらこの順で進めると、遠回りしにくいです。
手順1:遅いページの“最遅ビジュアル”を特定
手順2:DBで該当クエリの実行計画を確認
手順3:DB側の即効薬(インデックス/統計/集計済み)を当てる
手順4:モデルをスター型に寄せ、関係と列を整理
手順5:集計テーブル+複合モデルで“普段の閲覧”を高速化
手順6:ページ構成を軽くする(ビジュアル数、スライサー、相互作用)
まとめ
DirectQueryが遅いときは、「DBが遅い」の一言で片づけず、どこで時間が溶けているかを分解するのが最大の近道です。
-
DB側:インデックス、統計、ビューの整理、事前集計、同時実行、ゲートウェイ/ネットワーク
-
モデル設計:スター型、関係の単純化、キーと列の最適化、集計+複合モデル、DAXの軽量化
-
可視化:ビジュアル数、相互作用、スライサーの列選び、明細の出し方、操作回数の削減
特に効きやすいのは次の3つです。
-
集計を前に寄せる(DBまたは集計テーブル)
-
スター型に整える
-
1ページのクエリ本数を減らす
ここから手を付けると、最小の変更で体感が大きく改善しやすくなります。
コメント