Power BI レポートってデータソースへの接続モードでどれくらい速さに差が出るの？その① インポート vs DirectQuery vs ハイブリッド テーブル （Power BI Desktop 編）

# はじめに
Power BI を検討する際、最初に検討するべき項目の一つとして、データソースへの接続モード（インポート、DirectQuery など）があります。一般的に、Power BI では機能面とパフォーマンス面から、可能な限りインポート形式のデータセットでデータモデルを構築することが推奨されています。しかし、中には「リアルタイムに DB のデータを見たいから DirectQuery が良いのでは？」と考える方もいらっしゃいます。その結果、「Power BI レポートの表示が非常に遅い」という問題が発生することもあります。
本記事では、サンプルケースを用いて、実際に Power BI レポートのパフォーマンスを測定し、接続モードによってどの程度パフォーマンスに違いがあるのかを紹介します。

### 注意事項
本記事の結果は、サンプルケースで測定された検証結果です。実際の利用環境（レポートデザイン、データモデル、データ量、ネットワーク、データソースの種類、同時実行数など）によっては、パフォーマンスに大きな違いが生じる可能性があります。そのため、本記事はあくまで参考程度にとらえていただき、実際のパフォーマンスはご自身の実行環境で試してみることをお勧めします。

### (補足) データソースへの接続モードとは？
Power BIでは、データソースへ接続する際に、2つの接続モードを選択できます。
- インポート
    - Power BI データセットにデータを保持する
    - データ加工・結合処理が可能
    - データセットの更新によりデータを取得する
    - 比較的パフォーマンスが速い
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/44d01def-7493-a0ca-0dd5-5d9fdf1078a9.png)

- DirectQuery
    - Power BI データセットにデータを保持しない
    - データ加工・結合処理が可能であるが一部制限される
    - 常に最新のデータ取得が可能
    - 比較的パフォーマンスが遅い
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/17a678ff-df49-49e9-a1ae-0157668ae019.png)


(※データソースによっては DirectQuery が選択できないものもあり。詳細は[Power Query のコネクタ](https://learn.microsoft.com/ja-jp/power-query/connectors/)各データソースのコネクタを参照)

また、インポートと DirectQuery を 1 つのテーブル内で足したような、[ハイブリッド テーブル](https://learn.microsoft.com/ja-jp/power-bi/connect-data/service-dataset-modes-understand#hybrid-tables)という形態もあります。(増分更新のオプション)

- ハイブリッド テーブル
    - Power BI データセットにデータを保持する部分と保持しない部分がある
    - データ加工・結合処理が可能であるが一部制限される
    - 常に最新のデータ取得が可能なリアルタイムな部分と、データセットの更新で更新できる部分と、更新しないアーカイブ部分を構成することが可能
    - 一般的には、パフォーマンスはインポートより遅く、DirectQuery より速い
    - 増分更新のオプションのため、一般的にはデータソースはデータベース、項目に日付などの時系列データがあるテーブルが対象となる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/6feb2a9f-cf09-94bd-cecb-bc61651c277f.png)
    - 内部的にはデータがパーティションで区切られ、最新パーティションが DirectQuery モードで動作する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/609b2c8d-06b1-878a-a8f0-46285d4e4061.png)

その他にも、発行済みの Power BI データセットやAnalysis Services を利用する「ライブ接続」もありますが、今回は検証の対象からは割愛します。

# 今回使用した検証環境

- プラットフォーム ：Power BI Desktop
- データソース：Azure SQL Database
- 接続モード：インポート、DirectQuery、ハイブリッド テーブル

でレポートを表示した場合のパフォーマンスを測定していきます。

### 全体図
全体をざっくり表した図は以下となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/2f6bdd59-4ec7-6222-9d31-0e735aad033a.png)


### Azure 基盤 のスペック
- Azure SQL Database
    - モデル : vCore
    - コンピューティングレベル : サーバーレス
    - サービスレベル : 汎用
    - ハードウェアの種類 : Standard シリーズ (Gen5) : 最大仮想コア数 **16** で設定
    - リージョン : 東日本

- Azure VirtualMachine (Power BI Desktop 用）
    - OS : Windows Server 2022 Datacenter 
    - サイズ : Standard B8ms (**8 vcpu、32GiB メモリ**)
    - リージョン : 東日本

### データ内容
- 1日で Power BI のことを学ぶことができるハンズオントレーニング [Dashboard in a Day](https://powerbi.microsoft.com/ja-jp/diad/) で使用されるハンズオンデータ（ Excel、CSV ）を利用します。実績データ(売上データ)と日付テーブルに関しては、ハイブリッドテーブルを検証するため、2023年4月までデータを増幅させていますが、それ以外はそのまま利用します。今回は各接続モードに対応している Azure SQL Database へデータを載せて検証します。
- データ内容は以下の通りです(計 5 テーブル)
    |No|テーブル名|行数|補足|
    |:-:|:--|--:|:--| 
    |1|Date(日付テーブル)|4,017 行|日付、月、年などの情報（カレンダーテーブル）|
    |2|DIAD_M_Geography(地理データ)|176,931 行|国、州、地方、住所、郵便番号などの地理情報|
    |3|DIAD_M_Manufacturer(製造メーカーマスタ) |14 行|製造メーカーのID、名前|
    |4|DIAD_M_Product(製品マスタ)|2,412 行|製品ID、名前、製造メーカーID、セグメント、価格| 
    |5|DIAD_T_Sales(売上データ)|8,634,369 行|売上日(2014年1月～2023年4月)、製品ID、売上数量、売上金額、顧客|   

### データモデル
こちらも Dashboard in a Day で作成するデータモデルとほぼ同じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/3c0f9681-27b3-0d9f-f594-8570309199e8.png)

### 表示するレポート
こちらも Dashboard in a Day で作成するレポートとほぼ同じです。表示期間は 2018年1月1日～2023年4月30日(5年4ヵ月) とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/cfd0e5a3-7a17-865e-d959-e3eae26b6da5.png)


# 測定検証パターン

検証パターンとして、インポート、DirectQuery、ハイブリッドテーブルの 3 つのパフォーマンスを比較します。
|No|接続方式|データソース|
|:-:|:--|:--|
|1|インポート|Azure SQL Database|
|2|DirectQuery|Azure SQL Database|
|3|ハイブリッド テーブル|Azure SQL Database|

# Power BI Desktop でのパフォーマンス測定方法
今回は以下の時間を測定していきます。
- Power BI Desktop レポートのページ全体の表示時間
- 上記のうち、各ビジュアルの表示時間の内訳
- 上記のうち、各ビジュアルを表示するために実行される DAX クエリの実行時間

また、Power BI Desktop は初回表示時と 2 回目以降で表示速度が変わるため、**初回**と **2 回目**に分けて計測していきます。

これらを計測するために以下の 2 つのツールを使用します

### パフォーマンス測定ツール
- [パフォーマンス アナライザー](https://learn.microsoft.com/ja-jp/power-bi/create-reports/desktop-performance-analyzer)
    - **ページ全体の表示時間**と**各ビジュアルの表示時間**を取得
- [DAX Studio](https://daxstudio.org/)
    - 各ビジュアル表示ために発行される**クエリの実行時間**を取得

### 測定手順
1. 作成した Power BI Desktop を起動
※ただし、起動時は何もビジュアルを置いていない空白ページが開くよう設定しておく。（起動時に測定するページを開いてしまうと測定ツールを起動する前にページが表示されてしまい、初回ページ表示の時間測定ができないため）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/98281a07-f42c-5a83-79be-991b2aaf7d1a.png)


2. 外部ツールから DAX Studio を起動して、クエリのトレースを仕掛ける
Power BI Desktop の「外部ツール」→ 「DAX Studio」をクリックして、DAX Studio を起動
ローカルの Power BI Desktop のデータモデルに接続されていることを確認して、「Home」→ 「All Queries」をクリックして、データモデル上で実行されるクエリのトレースを開始
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/8d109ea8-ef85-64ac-c587-b384c830f352.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/b2fd4d09-4794-995a-aa67-e8c3575aa20b.png)


3. Power BI Desktop に戻り、パフォーマンス アナライザーを起動して、記録を開始
Power BI Desktop の「最適化」→ 「パフォーマンス アナライザー」をクリックする
表示された パフォーマンス アナライザー ペインで、「記録の開始」をクリックして、パフォーマンス測定を開始する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/58b11a8c-86d1-d110-fe5b-2e1468fbd052.png)

4. 測定を行うページを表示する
するとパフォーマンス アナライザー に初回表示の時間が記録されていく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/fe031d67-bce4-146d-a039-947c9dc8d411.png)

5. DAX Studio で、キャッシュのクリアを行う
初回表示時のキャッシュが残っているため、2回目表示測定のために、DAX Studio の 「Home」→ 「Clear Cache」ボタンをクリックしてキャッシュをクリアする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/e46a8d96-f685-fe50-4e19-e044fa46033f.png)


6. Power BI Desktop に戻り、パフォーマンス アナライザー の「ビジュアルを更新します」をクリック
するとパフォーマンス アナライザー に 2 回目表示の時間が記録されていく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/c86fd93e-1624-2d0d-dbe9-6b8f99574960.png)


7. DAX Studio の All Queries を確認し、初回表示時のDAXクエリ(5つ)と 2回目表示のDAXクエリの実行時間が記録されていることを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/768ceabd-7d04-de97-b382-27db9b60874b.png)

# 検証結果
それでは、上記条件で実行していったパフォーマンス測定結果を以下掲載していきます。
※表示時間の**太字**はその中での最長時間
## 1. Power BI Desktop - インポート

### 初回表示
|項目|ビジュアル|表示時間|(うち、DAX クエリ実行時間)|
|:--|:--|--:|--:|
|レポート全体の表示時間|-|**3332 ミリ秒**|-|
||カード|2901 ミリ秒|63 ミリ秒|
||縦棒グラフ|2635 ミリ秒|99 ミリ秒|
||地図|**3332 ミリ秒**|38 ミリ秒|
||折れ線グラフ|2466 ミリ秒|93 ミリ秒|
||散布図|2468 ミリ秒|**174 ミリ秒**|

### 2回目表示
|項目|ビジュアル|表示時間|(うち、DAX クエリ実行時間)|
|:--|:--|--:|--:|
|レポート全体の表示時間|-|**583 ミリ秒**|-|
||カード|430 ミリ秒|62 ミリ秒|
||縦棒グラフ|578 ミリ秒|79 ミリ秒|
||地図|321 ミリ秒|29 ミリ秒|
||折れ線グラフ|523 ミリ秒|59 ミリ秒|
||散布図|**583 ミリ秒**|**224 ミリ秒**|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/44566ccf-1568-9d25-179b-7a7dacbddcb1.png)


## 2. Power BI Desktop - DirectQuery

### 初回表示
|項目|ビジュアル|表示時間|(うち、DAX クエリ実行時間)|
|:--|:--|--:|--:|
|レポート全体の表示時間|-|**7655 ミリ秒**|-|
||カード|**7655 ミリ秒**|5355 ミリ秒|
||縦棒グラフ|7248 ミリ秒|4977 ミリ秒|
||地図|6179 ミリ秒|3561 ミリ秒|
||折れ線グラフ|6051 ミリ秒|3505 ミリ秒|
||散布図|7609 ミリ秒|**5359 ミリ秒**|

### 2回目表示
|項目|ビジュアル|表示時間|(うち、DAX クエリ実行時間)|
|:--|:--|--:|--:|
|レポート全体の表示時間|-|**5305 ミリ秒**|-|
||カード|4632 ミリ秒|4416 ミリ秒|
||縦棒グラフ|5266 ミリ秒|5032 ミリ秒|
||地図|3646 ミリ秒|3554 ミリ秒|
||折れ線グラフ|2885 ミリ秒|2631 ミリ秒|
||散布図|**5305 ミリ秒**|**5140 ミリ秒**|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/e1b2f2b2-c20e-e09f-0864-69c309f9e2f9.png)

## 3. Power BI Desktop - ハイブリッド テーブル

ハイブリッドテーブルは以下のように設定しています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/28a9c91e-8f89-e800-fda7-f6f9fa4bf924.png)
2014年～2021年まではインポート(非更新対象)
2022年はインポート(更新対象)
2023年1月～4月は DirectQuery
という設定になります。

### 初回表示
|項目|ビジュアル|表示時間|(うち、DAX クエリ実行時間)|
|:--|:--|--:|--:|
|レポート全体の表示時間|-|**3479 ミリ秒**|-|
||カード|2839 ミリ秒|384 ミリ秒|
||縦棒グラフ|2808 ミリ秒|526 ミリ秒|
||地図|3291 ミリ秒|872 ミリ秒|
||折れ線グラフ|3000 ミリ秒|898 ミリ秒|
||散布図|**3479 ミリ秒**|**1518 ミリ秒**|
### 2回目表示
|項目|ビジュアル|表示時間|(うち、DAX クエリ実行時間)|
|:--|:--|--:|--:|
|レポート全体の表示時間|-|**1347 ミリ秒**|-|
||カード|344 ミリ秒|77 ミリ秒|
||縦棒グラフ|421 ミリ秒|112 ミリ秒|
||地図|593 ミリ秒|473 ミリ秒|
||折れ線グラフ|981 ミリ秒|723 ミリ秒|
||散布図|**1347 ミリ秒**|**1176 ミリ秒**|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2642886/7bf44daf-5363-6f30-dd1a-b7afce96a3ea.png)

# まとめ
|接続モード|レポート表示時間(1回目)|レポート表示時間(2回目)|
|:--|--:|--:|
|インポート|3332 ミリ秒|583 ミリ秒|
|DirectQuery|7655 ミリ秒|5305 ミリ秒|
|ハイブリッド テーブル|3479 ミリ秒|1347 ミリ秒|

今回の環境では、やはり、パフォーマンスとしては、インポート ＞ ハイブリッド テーブル ＞ DirectQuery となりました。初回表示は 2 回目表示よりもすべての接続モードで 2 秒ほどプラスされており、初期処理的なものが入っているのではないかと考えられます。2 回目の数値で比較すると、やはりインポートは爆速で、DirectQuery はやや待たされる感じ、ハイブリッド テーブルは中間よりもやや速いという結果が出ました。
接続モードの選択は、要件やその時の環境によるとは思いますが、こちらの検証結果も一つの参考情報として検討いただければと思います。
次回は、Power BI サービスでの検証を行っていきます。

※ 2023年5月24日に Power BI サービス編 を公開しました
[Power BI レポートってデータソースへの接続モードでどれくらい速さに差が出るの？ インポート vs DirectQuery vs ハイブリッド テーブル （Power BI サービス 編）](https://qiita.com/rygondo/items/a8b69408c6dc8eddf1fe)