❄️

【SWTTokyo25レポ】 クエリパフォーマンスチューニングの傾向と対策

がく@ちゅらデータエンジニアです。

こんばんわ!!
Snowflake World Tour Tokyo 2025 は、とてもとても盛況でしたね!つーでいず!!!めちゃくちゃ熱いセッションばかりでした!

私がSWTTokyo25への参加はこのセッションを聞くためだ!!といっても過言ではないセッションがありました

Snowflakeの神エンジニア(Co-Founderにアジアナンバーワンエンジニアと言われた)yoshiさんのセッションです。

毎年、本当に質の高いセッション内容で、内容は正直「地味」かもしれませんが、Snowflakeでいかにパフォーマンスを出すか?を説明いただいたセッションです。
※御本人に一応Blogで書いていい?とは聞いたので、大丈夫だと思う(が、間違っていたり、そこはかいたらあかん!があったら指摘をくださいw)

アジェンダ

  1. パフォーマンスチューニングにおける基礎
  2. Snowflakeにおける典型的なパフォーマンス問題

大きく分けてこの2つでお話しいただきました。
まずは、パフォーマンスチューニングってものの説明と基本的にどう進めるか?のお話をいただき、Snowflake特有という流れ

パフォーマンスチューニングにおける基礎


なにはともあれ「目標設定」が大切!
ほんとこれ!
「なんとなく早くしたい」「なるべくはやくして〜」
とかは論外!
しっかり定量化して数値目標を建てないいけませんね。
速度とコスト、この両方をバランスよく行きたいところ

パフォーマンスチューニングはイテレーティブ

はい、至言いただきました!!
繰り返し試行錯誤を繰り返して、一つずつ進めていくことが大切
これはどんなことにも言えると思っていますが、パフォーマンスチューニングにもとっても重要

  • 一つを解決したら別の問題が
  • 2つ試したら解決→2つ目だけしたら改善する場合もあるので、時には、イテレーションを戻ることも重要

比較はできるだけ条件を揃えて

はい、また至言をいただきました!
ある日突然クエリが遅くなったら、同じ条件下で何が変わったか?を徹底的に、冷静に、先入観なく・・・かな?

想定通りに時間がかかっていることもある

はい、これもよーーくあることですね
スキャン量がどうしても多い場合など、マジしょうががない部分はあります。
※ただ、このあたりSnowflakeが勝手に改善してしまって、将来的に治ってしまってるってこともままあるんですよね

クエリコンパイル時間


  • クエリコンパイルは長いが実行が短いクエリもある
  • ネストはしないほうが良さそう

クエリコンパイルに関するベスプラ
できるだけシンプルに保つ

はい、また至言いただきましたーー

なにげに
「ロールのネストレベルを下げる」
も重要なんだなという学びがありました。

ロールのネストが深い(例えば、1000階層)とかにすると、それぞれのテーブルに対して、権限があるのか?の検査にすごく時間がかかるそうです。
ですので、ロール設計に関しても、できるだけシンプルに、複雑さは最小限にするのが大事そうです

クエリ実行

クエリ実行:テーブルスキャン

プルーニングが全く聞いていないことが一番下からわかる
→ スキャン量をいかに減らすか?はまず最初に考えることで、これについては「フィルタを効かし」てスキャン量をまず減らせないか?を考えることが何より大切


フィルタプッシュダウンとプルーニングは似てるように見えるが、実行中にもフィルタすることが「フィルタプッシュダウン」っぽい

こちらがクエリ実行時間をチューニングするためのベスプラ

  • 主キーが複雑するとフィルタプッシュダウンが効かない
  • → 一時テーブルにするとかCTEを使うなどして、先に計算してしまうなどして、条件を簡単にするなど
  • どうしてもダメな場合は、クエリアクセラレータ機能を使おう

クエリ実行:メモリ不足

スピルには、ローカルスピルとリモートスピルがある

スピルが悪いわけではない(必要なスピルもあるっちゃある
ソートする際にスピルは起きる

  • クエリの並列実行がやばい
  • CTEに同一SQLがあるとマテリアライゼーション(実体化)でおかしくなる
  • 集約は早い段階でやるべし

クエリ実行:メモリ不足のベスプラ

クエリ実行:集約

Snowflakeではビッグデータを使う
→分散して各サーバ?(コンピュート?)で集約してから全部を集約する

なので、複雑な集約(Case式をつかった)はヤバい

一次テーブルを使うのも良き

ベスプラ

クエリ実行:結果生成・データ挿入

  • VARIANT型やJSON型はリザルト作成で死ぬ
  • ネイティブ型に比較して、2倍とか3倍とかの時間がかかることも

クエリ実行:結合順

  • 結合はSQLに書いてあるとおりに結合するわけではない
  • データに大きな偏りがある際に、オプティマイザーがご検知することはある → 基本的にオプティマイザーは、隔たりのない偏差?偏り?でデータが有るという前提で動くことが多いため
  • プレースホルダではなくnullにしておくのが良い
  • →これはその値がプレースホルダなのか、正当な値か?がはんだんできないため。nullにするとスキャン量を減らすことができる
  • 結合条件に or があるとJoin爆発の原因、ヤバいことになりがち
  • Joinは等価Join?がやっぱよさげ

ベスプラ

結合順に関しては、サポートに問い合わせてね!
そこはSnowflakeでやるし、駄目なパターンを教えてくれたらそれを反映できるし!!

まとめ

「遠慮なくサポートに頼る!!」
最後にまた至言いただきました

Snowflakeはここが強いからね、まじお世話になってます!!

ちゅらデータ株式会社

Discussion