NTT DATA TECH
❄️

Snowflake Notebooksが速すぎる

に公開

クエリ最適化、使いこなせてますか?
データ分析業務でSnowflake Notebooksを使っている私が、良さを最大に引き出すテクニックをご紹介します。大容量データを爆速で集計して、コーナーで差をつけましょう!

はじめに

NTTデータの齊藤青葉です。クラウドDWHであるSnowflakeのデータを使って分析する毎日を過ごしています。
 もともと、Jupyter Notebookで集計分析を行っていましたが、Snowflake Notebooksを使ってみたところ集計スピードが上がり、クラウドBIツールとの相性も良いこと、自動化もできることから良さに気づき、乗り換えて使っています。
 データ基盤としてSnowflakeを使う企業も増えつつあり、そんな皆様がSnowflake環境を使いこなす一助になれたらと思います。

3行で結論!

まずは3行で結論です。

  • Snowflake Notebooksはスゴいけど使えば良い(万事最適化される)ってわけじゃない!
  • pandasに頼らない!仕様を知って爆速で分析しよう!
  • 利用コストは安い!ただしNotebookインスタンスには注意!!

気になった方は以降を読んでハートを押してください♡

そもそもなんでノートブックを使うの?

Snowflake Notebooksの詳細を語る前に、Jupyterも含めなぜノートブックを使うか?を考えると、「Pythonを使って集計・分析を行いたいから」になると思います。
 Pythonはデータ分析のライブラリが優秀で、高度な集計や分析・可視化が簡単にできます。データフレームというデータオブジェクトに対する操作を順次実行することで簡単にデータ分析が可能です。
 もし、SQLだけで複雑な集計をする場合、長く混沌とした可読性のないコードになるため、順を追ってデータ操作できることはとても嬉しいですね!

ではなぜSnowflake Notebooksか?

結論から言うと、(使いこなせば)処理が速い、それゆえに安価、クラウドBIツールと相性が良い、の3本だと私は考えています。それぞれに触れていきます。

処理が速い

Pythonにはpandasというデータ分析に特化したライブラリがありますが、使う際はデータフレームというオブジェクトに、すなわちPythonの利用しているメモリ領域にデータを読み込む必要があります。
pandasは単一プロセス実行が基本ですので、データが大容量だと読み込みに時間がかかります。容量が大きすぎるとメモリが落ちて水の泡になることも...。
この、「Python領域へのデータロード」を行わなくてもPythonでデータ分析できる仕組みが、Snowflake Notebooksにはあります。
pandasではなく、Snowparkというライブラリのデータフレームを使えば、驚くほど集計が高速化します。環境やクエリによりますが、私はだいたい4倍くらい速い感覚でした。

Snowparkデータフレームの何がすごい?

  • データオブジェクトではなく、実態はただのSQL
  • それゆえPython領域にデータをロードする必要がない
  • 結果が必要になるまでデータを取得しない遅延評価という仕組みでクエリ最適化を行う
  • データ処理は基本的に並列処理

何言ってんだ?という声が聞こえたので、具体例で説明します!

  • cell2はテーブルアクセスのある任意のSQLに読み替えてください。ただし、このセルはSQLモードでなく、Pythonモードで行ってください(さもなくば後述の遅延評価されず即時実行されてしまいます)。
  • cell3ではデータフレームにデータを詰めているように見えますが、内部では実行計画にSQLをスタックしているだけです。
  • cell4は簡単なフィルター処理ですが、このセルを実行しても、同様に実行計画にスタックされます。
  • cell5はいわば「結果が必要な処理」です。この瞬間、内部では溜まっていた実行計画から1つのSQLを作成し、実行することで一気にデータ取得を行います。cell4のフィルター処理はWhere句に変換されて元のSQLに統合されるイメージです。
  • こんな具合で、オブジェクトにデータを詰めることなく、裏でSQLを育てて最後に実行という形でデータを捌くので、速く、クエリの最適化ができます。
  • データに対しては1回SQLを投げるだけなので、Snowflakeの仕様に則って基本的に並列処理で取得されます。

注意点

上記が高速データ処理が実現できる理由ですが、注意が必要です。
例えば、もう一度cell5のshow()など、結果を求める処理を実行した際、もう一度cell2~cell4までの統合クエリが生成され、データ取得が行われることです。データの実態が詰まったデータフレームではないので当然ではあるのですが、一般的なコーディングの感覚と乖離があることを知っておいてください。
 あるデータフレームを複数回利用する際は、snowflakeの一時保存領域に明示的にキャッシュするcache_result()を使いましょう。

 いわばデータのセーブ機能ですね。内部でもう一回最初からやり直すということが起きなくなるので、必須のテクニックです!
逆にキャッシュせずに無駄にshow()を連発するのはやめましょう。余分なクエリコストがかかります。

最速で処理するために

  • Snowparkのデータフレームを使おう!
  • 遅延評価の仕組みを理解してデータ処理を実装しよう!
    これができれば爆速アナリストの誕生です。
    具体的なSnowparkの記法については、任意のAIに聞けば簡単にわかるためご心配なさらず。

pandasのデータフレームは使っちゃダメなの?

いいえ!そんなことはありません。pandasはMatplotlib等と組み合わせたビジュアライズに強いので、notebook内でヒストグラム等の描画を行う際はsnowpark DFからpandas DFに変換することをおすすめします。ただし、pandas DFに変換する際にメモリにデータがロードされるので、大容量データだと時間がかかること、変換自体がデータの実体を求める処理であり、遅延評価が解除されることをお気をつけください。
 Snowparkでデータ処理して集計結果データなど小さいデータをpandasに変換するのがベターです。

Snowpark pandasデータフレームについて

両データフレームの中間にあたるSnowpark pandasデータフレームというものがあります(笑)。pandasの記法で書けば裏でsnowparkデータフレームとして扱いますよ、という機能です。
ただ、(Snowpark DFでもそうですが)結局のところ、実態はSQLであることや遅延評価の概念を理解していないと高速化できないので、「pandasの記法で書くだけで裏でめっちゃ最適化してくれる!」という浅い理解で使い続けるのは危険です。
私個人としては、はじめはSnowparkを使って、別の言語仕様である感覚をつけることをおすすめします!

安い

Snowflake Notebooksは、コンピュート時間に応じて課金される仕組みであるため、高速でデータ処理できればそれだけ安いコストで済みます。

注意点(超重要)

ノートブックを作成する際に、クエリウェアハウスとNotebookウェアハウスを選択しますが、Notebookウェアハウスについては課金を抑えるために極力最小のものを選択しましょう。私が使っている感覚ではここのグレードを上げたところでパフォーマンスはそこまで変わりません。処理に時間がかかっている原因はウェアハウスのグレードではないことが多いです。
 また、Notebookウェアハウスは、セッションが立ち上がっている時間に対して課金されるので、実行中でなくとも課金されます。アイドルタイムアウトは最小の時間に設定したうえで、コーディング中など実行していない時間は極力セッションを終了させることで、課金額を大幅に抑えられることを知っておいてください。
あとは、重いクエリ事故を防ぐためにも、STATEMENT_QUEUED_TIMEOUT_IN_SECONDSを設定しておくことをおすすめします。

ALTER NOTEBOOK my_nb SET IDLE_AUTO_SHUTDOWN_TIME_SECONDS = 900; -- 15分

BIツールとの相性が良い

Notebookで作ったデータフレームはSnowflake内のユーザ領域のテーブルに書き出すことができます。

df.write.mode("overwrite").save_as_table("ANALYTICS.USERDATA_SUMMARY")

それをそのままTableauやSigmaのようなイケてるクラウドBIツールから読み込み、簡単にダッシュボード化することができます。接続もセキュアで最適化されており、何よりデータ基盤からBIまでがクラウドで完結するため、「低コスト、高速導入、スケーラブル、リアルタイム、安全」など様々なメリットがあります。

さいごに

紫式部もびっくりの長文に付き合っていただいてありがとうございます。Snowflake Notebooksの良さが少しでも伝わっていたら幸いです。いいねください。

NTT DATA TECH
NTT DATA TECH
設定によりコメント欄が無効化されています