Snowflake を使うときに初心者に気をつけてほしいこと

この記事は[Snowflakeアドベントカレンダー](https://adventar.org/calendars/5085)の10日目の記事です。

今日は私が Snowflake を使いはじめて失敗したことを中心に、**不幸な事故を繰り返さないため**に初心者の方に気をつけてほしいことを書こうと思います。


# スピル見てない

Snowflake ってとっても高速にクエリを実行してくれるので、ついつい**プロファイルを見るのをサボったり**してしまいますよね？

これは**架空の話**なんですが…
あるとき、めっちゃクエリが遅かったんです。
あー、遅いねーって思ってた。
よーく、プロファイルを見ると、**スピルの数字がめっちゃ増えていた**わけですよ。

![Query_Detail__0198ceaf-0081-b15a-0000-0af90011432a_と_Slack___prj_社内_snowflake_ninja___Chura_DATA_と_外部テーブル_プルーニング_Snowflake_-_Google_検索.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75613/c265edad-a671-ef62-edc5-53225d7a2fb9.png)

うーん？スピルってなんだっけ？

https://community.snowflake.com/s/article/Recognizing-Disk-Spilling
>When Snowflake cannot fit an operation in memory, it starts spilling data first to disk, and then to remote storage. These operations are slower than memory access and can slow down query execution a lot.
>超意訳：Snowflake はメモリで処理できなくなったら、データはローカルディスクに溢れ、さらに続くとリモートストレージに溢れます。これはメモリでやるよりとっても遅い。

プロファイルをもう一度見ると、77.67GBもスピルしてることがわかります。
※ちなみに少し前の参考情報ですけど、Snowflakeのローカルディスクは160GB位っぽいです。

これはもしかして、ウェアハウスのサイズを上げていれば、もっと早く安く実行できたのでは？
もしくは条件絞ってメモリに乗るような集計にしてあげたら良かったのでは？


# プルーニングみてない

上記のようなことがあってもやっぱり Snowflake は高速ですよね？

**架空の話です。**
プルーニングのことを解決した後は、もう楽勝だろ〜って鼻歌交じりで、クエリを叩いていたわけです。

あー、**マイクロパーティションは最高のアーキテクチャだー**って思いながら、あくびをしていたところ、あれ？
このクエリってもっと早くなかったっけ？

前回の反省から、**「よっこいしょういち」**とつぶやきながら、プロファイルを見てみると。

![Query_Detail__0198cf1f-008b-5243-0000-0af900118c0a_と_Slack_____prj_社内_snowflake_ninja___Chura_DATA_と_外部テーブル_プルーニング_Snowflake_-_Google_検索.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75613/a8baef5d-d4e1-69bd-3d59-9d30b62becbc.png)

あれ？プルーニングされてなくない？

プルーニング(剪定、枝刈り)とは・・・
https://community.snowflake.com/s/article/understanding-micro-partitions-and-data-clustering
>How data is organized into micro-partitions has a significant impact on pruning performance. 
>超意訳：データがどのようにマイクロパーティショニングされるかはプルーニング(剪定)パフォーマンスに超影響があります。

いくらSnowflakeのマイクロパーティションが超イケてるいっても、プルーニングがうまくいかないと無駄にスキャン走ってしまうってことか。

こういうときは

1. クエリを見直す
2. クエリが問題ないなら、クラスタリングキーを検討してみる

- 参考：[クラスタリングキーを選択するための戦略](https://docs.snowflake.com/ja/user-guide/tables-clustering-keys.html#label-clustering-keys-strategies)

マイクロパーティションを理解して、うまくプルーニングされるように調整しましょう。

# クレジットの使用量みてない

**架空の話です**

「最近、Snowflakeのユーザ増えたなー。社内でも布教に成功しつつある」

あれ？そういえば最近クレジットの使用量みてなかったな・・・

![Billing___Usage-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75613/7b837fe6-eb17-ac6c-4ab4-7a74b9451dcb.png)

一瞬ギャグかなって思って二度見しちゃいました。

皆さんはこうなる前にリソースモニターの設定を忘れずに、通知さえ来れば、助かるから…。

- 参考：[リソースモニターの操作](https://docs.snowflake.com/ja/user-guide/resource-monitors.html)

# Fail Safe みてない

**架空の話です**

「あー、データ、間違ってCOPYしちゃった。消そう〜。」
「あー、また、データ、間違ってCOPYしちゃった。消そう〜。」
「あー、またまた、データ、間違ってCOPYしちゃった。消そう〜。」
「あー、またまたまた、データ、間違ってCOPYしちゃった。消そう〜。」
…何度か繰り返す…

こうするとFailSafeにどんどんデータが溜まっていきます。
**※大昔の架空の話なのでスクショはありません**

FailSafeに入ったデータはデフォルトで7日間消えません。
**一度データを入れたら、7日分の課金は覚悟してください。**
極端な話、1TBのデータを間違えてCOPYしてテーブルに入れた後、テーブルをDropしても、1TB分が7日間は課金されるという意味です。
もし、COPYを挟んで試行錯誤するのであれば、永続テーブル（通常のテーブル）ではなく、仮テーブルか一時テーブルを使いましょう。

- 参考1：[Snowflake に試験的にデータを入れるときは TRANSIENT にしてストレージ課金を減らそう](https://qiita.com/foursue/items/35390973336845098657)
- 参考2：[仮テーブルと一時テーブルの使用](https://docs.snowflake.com/ja/user-guide/tables-temp-transient.html)


# 終わりに

いかがでしたか？

**人は失敗しながら強くなる。
私はいつもそう思って生きています。
一番早く失敗したものだけが、一番早く前にすすめるのです。**

**強く生きよう。**

そう誓った師走の深夜でした。