TableauのViewの速度改善を色々試してみた

Adways Advent Calendar 2020 17 日目の記事です。


 

こんにちは!半田です。
今日は12月23日ですね。クリスマスイブの前日は休みという感覚がなかなか抜けない平成生まれです…上皇さまお誕生日おめでとうございます。
今回は普段業務で使用しているTableauのViewの速度改善をユニットのOKRとして取り組んだ内容について、それぞれのやり方と感想とともに紹介していきたいと思います。OKRとはなんぞやと思った方は杉内さんの下記記事をご参照ください。

OKRを決めるまでの背景

私のユニットでは主に運用型広告の支援ツールの開発、運用を行っています。
媒体レポートデータをAPIで取得し、営業レポートの支援が主な利用用途になっていましたが、エンジニアもデータを見る習慣をつけよう!となり、Tableauで広告運用データを可視化するようになりました。
表示したい項目が増えていくにつれデータ表示や都度フィルターがかなり重くなっていくのはTableauを使っている方なら経験あるのではないでしょうか。(今回の場合、最長30秒近く待つことも…!)
これらを改善するためにチームで速度を早くするためにどうするか試行錯誤しました。
検討の結果、OKRの目標値としてレスポンス5秒以内と設定しました。

データ分析基盤構築

(本題が知りたい方は飛ばしてください)

APIから取得したデータをTableauで表示するために、今回はAmazon Athenaを使用しています。
APIで取得したデータを閲覧しやすい形に加工し、S3にアップロード後Athenaで参照するシンプルな構成です。

f:id:AdwaysEngineerBlog:20201223104958p:plain

速度改善で実際にやったこと

ここからはサンプルデータを使用し、実際に行った速度改善について、実施方法と体感どの程度早くなったかの感想を述べていきたいと思います。

Tableau Desktopでパフォーマンスの可視化を行う

Tableau Desktopの機能である、パフォーマンスの可視化を行うとどこに時間がかかっているかがわかります。こちらは直接的に速度が早くなるわけではないですが、原因究明に役立つ指標となります。
ヘルプ > 設定とパフォーマンス > パフォーマンスの記録の開始を押下後、動作が重い処理を行う(フィルターを動作させる、レコードをクリックしてフィルターするなど)> ヘルプ > 設定とパフォーマンス > パフォーマンスの記録の停止を押下
以上の手順を行うと下記のようなグラフが出てきます。
グラフをマウスオーバーすると、シート名やデータソース名が表示されます。

f:id:AdwaysEngineerBlog:20201223105021p:plain

この表を確認すると、「Rendering」と「Computing Layout」と「Compile Query」に時間がかかっているようです。それぞれ原因と対策は以下のようになります。

  • Rendering
    • サーバーレンダリングに時間がかかっている。TableauのView側で対応する術はなし。
  • Computing Layout
    • グラフの描画に時間がかかっている。グラフを減らしたり簡素化すると改善する。
  • Compile Query
    • 複雑なクエリを実行しているので応答に時間がかかっている。単純なクエリに変更したりJOINをやめると改善する。

Tableauで速度改善が見込める「Computing Layout」と「Compile Query」を改善していきます。

不要なレコードデータをフィルターして抽出

今回のようにデータの参照先にAmazon Athenaを使用している場合、その他BigQuery、TableauServerなど外部通信が発生するデータソースを使っている場合、データの抽出をすることで大幅な速度改善が見込まれます。
また、その上で抽出する際に不要データを予め除外しておくことで更に速度改善が見込まれます。
今回は元データは2016年からデータがあったところ、2018年以降のデータに制限後抽出を実行するようにしました。
今回紹介する施策の中で一番効果的でした!

f:id:AdwaysEngineerBlog:20201223105131p:plain

グラフの数を減らす

Computing Layoutを改善するためには一度に描画するグラフの数を減らすことで改善されます。
改善するViewには29個のグラフがありました…!(今思えば多すぎる…)
ただし今回はグラフの数は減らさない(すべて必要なグラフ)前提付きでした。

グラフの数を減らさずに表示を軽くする方法として、グラフをカテゴリごとにブックを分割する方法があります。
例として以下のようなダッシュボードがあった場合、「売上の目標と実績」「顧客分析」を別カテゴリとして別のブックに分けると速度改善が見込まれます。
ただし、月ごとの売上と顧客分布を俯瞰して見たい!といった利便性はなくなってしまうので一長一短ではあります…。

f:id:AdwaysEngineerBlog:20201223105100p:plain

フィルターの適用範囲を限定させる

フィルターを追加する際に、ブックにシートを配置後に表示される「フィルターとして使用」ボタンのみで適用すると、関連するすべてのシートにフィルターがかかるようになります。
シート数が少ない場合は特に問題ないですが、フィルターをかけるシートのグラフ描画が多い場合、フィルターをかける度に描画処理が動くため1回毎の待ち時間が多くなります。裏側では1つ1つのViewの表示毎にクエリが実行されているため時間がかかるようです。
これを解決するために、フィルターをダッシュボードアクションに置き換えることでフィルターの適用先を制限します。
ダッシュボード > アクション からアクション一覧を表示し、アクションの追加 > フィルター を押下し新規作成します。

f:id:AdwaysEngineerBlog:20201223105154p:plain

今回は売上実績をクリックすると顧客概要のみフィルターがかかるようなアクションを追加しました。

f:id:AdwaysEngineerBlog:20201223105219p:plain

これを行うことにより、クエリの実行回数の削減ができるだけでなくフィルターの個別操作ができるため、全体確認グラフと詳細確認グラフの用途分けができるようになります。

計算済みデータを抽出するようにクエリを操作する

※データソース元から操作できる場合のみ
Tableauの計算フィールドの作成をしている場合、描画するたびに計算処理が実行されるようです。
特にLOD表現を多用していると内部の計算処理に時間がかかります。

どうしてもTableauで使うデータは詳細データが多くなってしまうので、計算処理が多くなりがちです。そこで、事前に計算済みデータを出力させるとTableau側での計算処理が少なくなり、表示速度が改善されます。
以下のような顧客単位の月ごとの売上高を計算するViewを予めAthenaで作成しておくことで、Tableauでの計算処理がなくなり速度が改善されます。

CREATE OR REPLACE VIEW sample_customer_month_cost AS 
SELECT
  year("date") AS year,
  month("date") AS month,
  "customer_id",
  SUM("sales") AS month_sales
FROM
  sample_store
GROUP BY year("date"), month("date"), "customer_id"

最後に

今まではデータの表示速度を考えずに見たいデータをただ可視化して分析するだけでしたが、また違った視点でTableauを見直すことができました。
ここまでに挙げたパフォーマンス改善施策を駆使した結果、フィルター待機時間が約30秒から約5秒に短縮されました!
効果として大きかったものは、「レコードデータをフィルターして抽出」と「計算済みデータを抽出するようにクエリを操作する」です。
簡単にできるものが多いので、これを機に速度改善してみてはいかがでしょうか。少しでもご参考になれば幸いです。


 

次は小松さんの記事です。