💹

Snowflake×Tableau:パフォーマンス・コストの最適化テクニック集

2024/05/20に公開

この記事は何

代表的なデータウェアハウスの1つであるSnowflakeと、代表的なセルフBIツールの1つであるTableauのコラボレーションはとても強力です。

一方で、SnowflakeにTableauから大量アクセスされることへのコストの懸念を抱えたり、ライブ接続の環境下でダッシュボードのパフォーマンスを出すことに苦戦する方もいると思います。

そこで、今回はSnowflakeとTableauを最大限活用するために、Tableau側・Snowflake側両方の視点から、パフォーマンスとコストの最適化に使えるテクニック集を紹介します。

1. Tableau側で出来る対策

まず最初は、Tableau側で出来る対策です。Tableau側は、Snowflake側へのクエリの実行数を減らすことが基本的な対策と言えます。

1-1. 抽出を利用する

まず最初は Tableauの抽出の利用です。ライブ接続でのメリットが目立つSnowflakeですが、コスト節約の視点では抽出はかなり有効な選択肢です。

データの接続方式を「抽出」に変更すると、TableauはインメモリデータエンジンであるHyperでデータ集計を行うようになります。

抽出を利用する場合、Tableauは抽出の作成と更新にしかSnowflake側のウェアハウスを動かしません。 そのため、Tableauの操作の度に都度クエリが走る可能性が高いライブに比べ、Snowflakeのウェアハウスの稼働時間を劇的に削減させることが期待できます。

Hyperによるデータ集計は非常に高速であり、数千万行くらいまでのデータであれば、ほとんどのケースで数秒以内に結果を返してくれます。一般的なダッシュボードでは、十分すぎるレスポンス速度と言えるでしょう。

一方で、Hyperを検討しづらいのは以下のような状況です。

  1. 接続先のデータの容量が多く、集計や抽出作成に時間がかかる(数億行以上に及ぶ場合や、列数が多いデータなど)
  2. 接続先のテーブルの情報を、リアルタイム(秒・分単位)に反映する必要がある
  3. 抽出の利用に伴うデータの移動に、セキュリティやポリシー上の懸念がある
  4. Tableau側の環境に十分なストレージ容量がない

ライブでの接続が必要な場合は以下を検討していきましょう。

1-2. 自動更新の「一時停止ボタン」を利用する

Tableauのツールバーにある自動更新の一時停止の利用する方法です。

こちらを一度押すと、自動更新を再開するまでの間、Snowflake側へのクエリ実行を防ぐことができます。※一時停止の間は可視化も行われません。

シンプルですが、ダッシュボードの構築中や、フィルターの選択肢をまとめて変更したい場合などに活用できる効果的なテクニックです。

1-3. 「フィルターの適用ボタン」を追加する

Tableauのフィルターに 「適用ボタン」を追加する方法です。

これは、複数選択のチェックボックスなどのフィルタータイプにおいて、ユーザーがフィルターのチェックボックスを変更する度にクエリが発行されることを防ぐことが出来ます。

「適用ボタンの追加」は対象のフィルターを右クリック→カスタマイズ→「適用ボタンを表示」から行えます。(単一選択など一部のフィルタータイプには利用出来ません)

なお、上記適用ボタンは個別のフィルターに対する設定です。複数のフィルターの変更を同時に適用したい場合には、上記の自動更新の停止を通して行う必要があります。また、以下の動画では元Tableau社・現Alation社の杉村さんによる「複数のフィルターの一括適用ボタン」を作成するテクニックが紹介されています。
https://www.youtube.com/watch?v=BtgS3_tI-aU
ユーザーに分かりやすくて便利な一括の適用ボタンを作成したい場合は、こちらもご検討ください。

2. Snowflake側で出来る対策

続いてSnowflake側で出来る対策です。Snowflake側の対策は、最適なテーブルが用意されていることを確認した上で、マイクロパーティションやウェアハウスの設定を確認していくことを推奨します。

2-1. 接続されるテーブルの最適化する

ダッシュボードの接続先であるテーブルの最適化(データマートの作成)は、Tableau側を含めた追加の実装が必要になる選択肢ではあるものの、劇的な改善効果も見込めるチューニング方法です。

  • テーブルに可視化に利用しない不要なデータが含まれており、行数が必要以上に膨らんでいる
  • テーブルの行の粒度が必要以上に細かくなっており、行数が必要以上に膨らんでいる
  • 複雑なCASE式がSQLで毎回実行されている
  • 複雑な結合やユニオンが全てのSQLで実行されている

などの理由による大幅なパフォーマンスが悪化が起きている場合、それらを解決したテーブルの作成を検討してみましょう。

テーブルを最適化する場合は、一般的にはテーブルの作成・更新ジョブをELTパイプラインに組み込むことで行いますが、Snowflakeでは実体化されたテーブルの作成方法として以下のオプションも検討できます。

各テーブルタイプの特性や課金体系を理解した上で、最適なものを利用しましょう。

2-2. リザルトキャッシュを活用する

他ユーザーも含めた実行済みのクエリ結果を使い回すことができるSnowflakeのリザルトキャッシュを活用する方法です。

リザルトキャッシュが利用された場合、ウェアハウスを動かす課金が発生しないだけではなく、実行済みの結果を通常ミリ秒単位のレスポンスで取得出来るため、コストとパフォーマンスの両面で非常に大きな効果が期待できます。

通常、ダッシュボードから発行されるクエリの多くは、Snowflakeのリザルトキャッシュの実行要件を満たすことが多いため、特別に意識しなくても活用出来るケースが多いと思います。

しかし、リザルトキャッシュ非対応の関数を利用している場合など、制約に引っかかりリザルトキャッシュを利用できていないこともあります。SnowflakeのクエリプロファイルQUERY_HISTORYを確認し、リザルトキャッシュを活用が出来ていない場合には対策を行いましょう。

2-3. 接続されるテーブルのクラスタリングを意識する

特定の列の値を使ってテーブルを並び替えるクラスタリングも、ダッシュボードのパフォーマンスの改善にとても役立ちます。多くのダッシュボードでは、何らかの日付列の値を使ってフィルターをかけるため、接続先のテーブルも、その日付列を使ってクラスタリングすることで改善できるケースが多いためです。

クラスタリングは数TBなどの巨大なテーブルにしか効果がないと思われがちですが、ダッシュボードのデータマートによくあるような数百MB程度のテーブルでも、十分にパフォーマンス改善効果があります。 (身近では10秒程表示に時間がかかっていたダッシュボードが、クラスタリングの最適化のみで5秒以下に改善する事例もありました。)高速なパフォーマンスを求められやすいダッシュボードの領域では、クラスタリングの検討は不可欠な要素のひとつです。

特定のテーブルのクラスタリングの状態を確認するには、SYSTEM$CLUSTERING_INFORMATIONを利用します。また、クラスタリングに問題ない場合でも、クエリプロファイルQUERY_HISTORYを見ることで、実行されたクエリが「実際にプルーニングされているか」も確認しましょう。

クラスタリングが適切にされていない場合、以下の3つのアプローチを検討できます。

詳細は、SELECT社による以下の記事を参考にしてください。
https://select.dev/posts/snowflake-clustering

2-4. ウェアハウスの設定を最適化する

テーブルの構造やクラスタリング周りに課題がないにも関わらず、依然パフォーマンスに問題がある場合、Snowflakeのコンピュートリソースであるウェアハウスの最適化を検討しましょう。

まずは、SnowflakeのQUERY_HISTORYを確認し、パフォーマンスのボトルネックを特定します。

ここでは以下の3つのパターンを紹介します。

  1. 個別のクエリの実行時間は短いが、キュー待ちが多い場合
  2. 全体的にクエリの実行時間が長い場合
  3. 特定のクエリの実行時間が多くの時間がかかっている場合

問題の内容に応じて、それぞれ以下のアプローチで解決していきます。

1. 個別のクエリの実行時間は短いが、キュー待ちが多い場合

個々のクエリの実行時間は許容範囲であるものの、キューに入ったクエリが多く発生することでトータルの待ち時間が長くなるパターンです。この場合、同時実行が可能なクエリの数を増やすために、マルチクラスターウェアハウスの設定や、ウェアハウスサイズの変更を行うことが推奨できます。

なお、同時実行可能なクエリに一定の影響を与えるパラメーターにMAX_CONCURRENCY_LEVEL がありますが、このパラメーターは同時実行数の上限を厳密に制限するものではないほか、パフォーマンスのデグレにつながるリスクがあるため、引き上げは一般的に推奨されていないようです。

2. 全体的にクエリの実行時間が長い場合

個別のクエリの実行時間が許容範囲を超えている場合です。この場合、ウェアハウスのサイズを引き上げることで、すべてのクエリに対する処理性能を上げることが推奨できます。

通常Snowflakeのウェアハウスを選択する際は、ウェアハウスサイズの引き上げによってクエリの処理時間が縮まり、結果的にコストはほぼ変わらないと言ったことがよくあると思います。しかしダッシュボードの場合は、数秒で終わってしまうクエリも多い性質上、ウェアハウスの最近課金時間である1分の課金が発生するケースが多いです。そのため、クエリの速度改善が改善したとしても、どのみち1分課金されてしまうため、速度改善によるコストメリットが受けにくい点も特徴と言えるでしょう。

3. 特定のクエリの実行時間が多くの時間がかかっている場合

特定のクエリの実行に時間がかかっている場合には、リソースを多くするクエリの処理を別のリソースにオフロード出来る Query Acceleration Serviceの検討も一つの手です。

一方で、Query Acceleration Serviceによる恩恵が受けられるクエリには条件があります。処理時間がかかっている特定のクエリを、SYSTEM$ESTIMATE_QUERY_ACCELERATIONを使うことで、効果を受けることができるか確認しましょう。(現時点の制約だと満たせないケースが多い印象です)

また、実行時間が長期化している特定のクエリのパフォーマンスが、文字列の部分一致などの検索に課題がある場合、検索最適化サービスを検討するのも良いでしょう。

その他

Snowflake社による以下のホワイトペーパーでは、Snowflake×Tableauを利用する際のベストプラクティスが紹介されています。より多角的な視点でのベストプラクティスを知りたい方は、こちらも参考にしてください。
https://www.snowflake.com/resource/best-practices-for-using-tableau-with-snowflake/

SnowflakeとTableauのパフォーマンスやコストを詳細に分析していくには、各クエリの発行元のワークブックやワークシートの特定が不可欠です。以下の記事では、TableauのダッシュボードとQueryIDを紐付ける方法を紹介しています。こちらも参考にしてください。
https://zenn.dev/churadata/articles/fa51dcf0a83728

ちゅらデータ株式会社

Discussion