しばらく山とランは遠のいています

仕事、そしてコロナの関係でしばらく山やランからは遠ざかっています。来年の春から復帰できるようそろそろ運動再開していきたいと思います。ちなみに今、BIツールのPower BIが半分趣味になって、完全な運動不足になっています。20201020

2022年3月2日水曜日

Power BIが重くなった時のBufferの使い方

 Power BIを使い込んでくると必ずといっていいほど、速度問題にぶち当たります。

グラフの表示などレポート表示側の速度問題は、1ページあたりのビジュアル数を制限することに尽きるのですが、ソースデータの更新に時間がかかり出すと、このPower Query側の問題はなかなか解決できず困っている人が多いと思います。インポートモードからDirect Queryモードにするのはなかなかなハードルが高いですし、わたしもずっと苦労しています。

わたしは、まず、EXCELやJSON,XMLなど構造を持ったデータをソースデータにするのを諦めてCSVにすることだと思っています。使っていてこれらのタイプは便利なのですが、実感としてCSVとはかなり速度差があるように思います。

次にソースデータを読み込むときの様子を観察していると、同じソースが何度も読み込まれていることに気が付きます。この回数を減らさないといけません。これはPower Queryの特長で、分析に利用するデータセットに必要なクエリは毎回すべて動きます。またそれぞれのクエリは独立に動くので、同じデータセットが何度も読み込まれます。これを解決するのがTable.Buffer()、List.Buffer()、Binary.Buffer()ですが、よく理解して配置しないとほとんど効果がありません。効果を発揮する場所は限定的です。

MSのドキュメントにクエリ参照について説明があり、そこでにBufferについて言及があります。
https://docs.microsoft.com/ja-jp/power-bi/guidance/power-query-referenced-queries

クエリの参照は便利なのでよく使われると思います。ここで上記ドキュメントにある図を利用させていただきます。わたしも勘違いしていましたが、以下のQuery1の最後にTable.Buffer()を配置すると早くなるような気がします。でもこれは効果がないケースがほとんどです。以下の図のように、Power BIは以下のような参照構造のクエリは、結局3のクエリが動いていることになり、Query1のBufferは共有されず、3つ作られます。Bufferは一つのクエリの中でしか効果がなく、クエリ間では共有されません。

で、効果が出るのは、一つのクエリの中で、何度も同じテーブルを参照する(繰り返し処理など)ケースで効果が出ます。インポートモードの場合、Binary.Buffer()で根本をおさえ、あ重い処理で作成したテーブルやリストをクエリ内で何度も参照する場合は、Table.Buffer()、List.Buffer()が有効になります。
要するには一つ一つのクエリの処理が少ないケースではほとんどBufferは効果がないです。

また、クエリ参照でテーブルをいくつも作る場合、DAX側で「新しいテーブル」で作ればデータの再読み込みはないので、処理は速くなると思います。ただし、メモリを結構使うので、あまりたくさんこの方法でテーブルを作るとメモリ不足に陥る可能性もあります。

なお、Power BI デスクトップの設定にキャッシュサイズの設定があります。これはPower Queryエディタのステップ実行の画面のキャッシュで、ソースデータの読み込みの速度改善にはまったく効果はないです。

0 件のコメント: