データ ソース設定の プライバシー レベル ってどんな影響があるんだ？って話

複数のデータソースからイイ感じデータを集めてひとつのデータセットに収める、Power BI レポートを展開していくうえでとても便利な機能である。データソースごとの プライバシー レベル (分離レベル) を適切に設定してあげるとよいのだけど、目的としてはデータロードのパフォーマンス向上とちょっとした DLP。

# 大事なこと
異なるデータソースのクエリをマージするときなど、プライバシー レベル についてよく知っておいた方がよい。

- [Understand Power BI Desktop privacy levels - Power BI | Microsoft Docs](https://docs.microsoft.com/en-us/power-bi/desktop-privacy-levels)
- [Power BI Desktop のプライバシー レベルを理解する - Power BI | Microsoft Docs](https://docs.microsoft.com/ja-jp/power-bi/desktop-privacy-levels)

>The Ignore the Privacy levels and potentially improve performance does not work in the Power BI service. As such, Power BI Desktop reports with this setting enabled, which are then published to the Power BI service, do not reflect this behavior when used in the service.

Power BI Service (データセット) にはプライバシー レベルを無視するオプションがない。なので、Power BI Service で プライバシー レベルをきちんと設定してしてねってこと。
Power BI Desktop に比べ Power BI Service での ETL はなんか遅くね？とかなぜか スケジュール更新したら全行取得してんじゃね？とか起こる可能性があるのです。

そもそもの話として、Power BI Desktop の データソース設定(資格情報 / プライバシー レベル)と Power BI Service のそれは個別に管理されていて、pbix ファイルから引き継がれるものでもない。pbix ファイルには 接続先情報は含まれているけれども、資格情報とプライバシー レベルは含まれていない。

## Excel でも同じです。
[Privacy levels (Power Query) - Excel](https://support.office.com/en-us/article/privacy-levels-power-query-cc3ede4d-359e-4b28-bc72-9bee7900b540)

# "プライバシー レベルを無視すると、パフォーマンスが向上する場合があります" とは？
このオプションを選択したときどんな事件が起きるのかということではなく、どのような動作をするのかをまずは見ておくとよい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/5ce64fe4-b4e6-74e9-4970-39432f0435d5.png)
よその人に大事だったり機密のデータが開示されることがありますよというようなこと表示されてますね。

## どのような動作か
パフォーマンスを向上させる Power Query のそもそもな機能を制限なく有効とするもの。
"向上する場合があります" というのもデータソース次第だから。
クエリの状態にも影響する可能性があるから Power Query の クエリ フォールディングについて併せて理解しておくとよいかと。

例として、Excel ワークシート上にある 4つの製品についてそれら受注数量をマージしたい。受注の実績は 同じExcel ブックにはなく、Azure SQL Database にある。ふたつのデータソースからマッシュアップしデータセットにロードするイメージ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/5a1c05d4-67ca-757d-7a72-a48392f84e02.png)
Excel のテーブルからデータ型だけ合わせてそのままロード。それぞれの関連付けでできる各行を集計する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/d86264e2-a940-1d02-ff43-115257c36bf1.png)
必要な列だけをAzure SQL Database から抽出。関連付けできる列：商品ID とその数量
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/17128242-cfa9-0244-9be8-0de146307669.png)
マージを試みると、まずダイアログは表示される。個々のデータソースについてプライバシー レベルを設定していないので、どうする？って聞かれる。ここでは、プライバシー レベルを無視するオプションを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/681efbc4-c232-0a2b-6f6b-5276e30d9d02.png)
マージで得られた列から集計
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/8f6490f5-3643-b2d7-20f2-112cf9367fb1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/78a4b206-524e-fdc1-1fd8-db4dc1fddd60.png)

## 観察すべきことはなにか
ここでは Power Query (Mash-Up Engine) が Azure SQL Database にどのような問い合わせをしたか。Profiler で観察するというのもよいのだけど、Power BI Desktop にはちょうど良い機能 (クエリ診断 / Query Diagnostics) があるのでそれを使う。
[Query Diagnostics | Microsoft Docs](https://docs.microsoft.com/en-us/power-query/QueryDiagnostics)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/8c41724e-e2ca-eeda-91a1-91841260f370.png)
まだプレビューだけど問題ない。細かいことは置いといても何となくわかるはず。
スタートして、Power Query エディターは閉じない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/ee06b5b7-7061-b265-8287-77b9f3ccf399.png)
データセットを更新する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/4d8f4064-dc39-8f78-92d1-e50502bf2202.png)
停止する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/1cc560c1-e631-34d9-ce2c-449a6a2b377c.png)
すると、データセットにデータをロードするまでにどのような処理がされたかなど参照できるという機能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/d298d42f-cb5f-5181-e41a-fb7679848e6f.png)
ここで注目するのは、どのような T-SQL が発行されたのか。マージ元のクエリは 4 行でそれぞれ[商品ID] 1, 2, 3, 4 であった。Azure SQL Database に対しこれらを使い問い合わせていたということが推しはかれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/2ee70ab3-9c29-a144-8252-bb9963c6bfb1.png)
なので、Azure SQL Database のテーブルに無数の行数が存在していたとしてもPower Query では必要な行のみを取得するということがパフォーマンスが向上するということ。で、マージするための問い合わせに元のデータ、ここでは 商品ID が 異なるデータソースに渡されたということになる。渡されるデータが機微なものということもあるから、そのデータ渡しちゃっていいのかい？ってことは使う人が考えなければならないこと。

# プライバシー レベル を設定しよう
プライバシー レベル は 3 つあって、それら組合せで動作が決定する。"なし" も含めると 4 だけど、"なし" との組み合わせはできないので 3 つ。

- プライベート / Private
- 組織 / Organizational
- パブリック / Public

これらの組合せで確かめるとこんな感じになった。

|マージ取得元|マージ取得先|マージ元の情報を...<br />クエリの最適化を...|
|:---|:---|:---|
|**プライベート**|プライベート<br />組織<br />パブリック|**情報を渡さない**<br />**クエリの最適化をしない**|
|組織|プライベート|情報を渡さない<br />クエリの最適化をしない|
|**組織**|**組織**|**情報を渡す**<br />**クエリの最適化をする**|
|組織|パブリック|情報を渡さない<br />クエリの最適化をしない|
|**パブリック**|プライベート<br />組織<br />パブリック|**情報を渡す**<br />**クエリの最適化をする**|

なお、"情報を渡す" となる組み合わせであっても、データソースが対応していなければならないので必ず最適化されるということではない。クエリの最適化が期待できるだけであって、Power Query は可能であれば最適化を試みるというスタイルなのです。

## Power BI Desktop
データ セット設定 / Data source settings などから
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/7653f493-8673-b4d9-a10d-49c6e4852a6b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/c0b20e59-31b2-4852-7f80-c5556dfea2b6.png)

## Power BI Service
設定 / Settings → データセット / Datasets → データ ソースの資格情報 / Data source credentials から
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/5eb6fbce-601b-5dd1-d0ef-f7e492a60cfe.png)

## Power BI dataflows
Power BI データフローには プライバシー レベルを無視する設定がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/de203335-fc54-c6b0-7ab5-8f2e8d6490f0.png)
データ ソースのプライバシー レベルが確認できない状態だと、どうするの？ってなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/c79782b2-b2b6-fe57-53de-40c3b249f182.png)
データ ソースのプライバシー レベルが設定されていれば なにも聞かれない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/cf8f6ab8-5279-d703-3013-4327ccaaf16b.png)
他と同じく動作すると思ってたけど少々調子が悪いっていう事情があるので少々放置
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/d0505cd2-4987-6da1-9ce0-932dbbea7358.png)

## ちなみに Excel
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/c3a6e7a5-ecfa-0768-f087-049ef6e12795.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/3785f8bc-8e47-056b-fce8-9c87e375b92c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/2d734e0f-a22a-89a1-de32-ee4fae69a729.png)
まぁ一緒ね。

## 最適化ができかった場合はどうなるのか
全行を取得することになるけど、これは仕方がない。バッファしてくれるようだ。
更新完了が遅くなるというよりは、更新を早く終えることができないだけ。

# 思ったこと🙄
Power Query の最適化戦略はいくつかある。そのうち、できるだけ多くの行を取り込まないということなのだけど、これらは可能な限りというスタンスになっているのである。だって、本来の目的であるデータを取得するということが重要だから。多少しょっぱいことしてても、とりあえず目的を達成することは多いかな。
別途、タイムアウトっていうことがあるから、できる設定や調整はできるだけやっておいた方がよいねと。
データソースの組合せによって違いがあったりするのか🙄たぶんないと思うけど。

# その他
- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)