のサイズは、衣類のサイズのように段階で指定します。1段階上げると、単位時間あたりの 消費も上がります。
ここで重要なのが、消費が増えても総額が増えるとは限らないという点です。この回はサイズと分割の判断を扱います。
1. サイズを上げても総額は変わらないことがある
課金はサイズ × 起動時間で決まります。したがって、サイズを2倍にして処理時間が半分になれば、総額は変わりません。
| 条件 | 単位時間の消費 | 所要時間 | 総消費 | 待ち時間 |
|---|---|---|---|---|
| 元のサイズ | 1 | 60分 | 60 | 60分 |
| 2倍(きれいに半減) | 2 | 30分 | 60 | 30分 |
| 2倍(あまり縮まない) | 2 | 45分 | 90 | 45分 |
| 2倍(ほぼ縮まない) | 2 | 55分 | 110 | 55分 |
2行目なら費用そのままで待ち時間が半分になります。これは明確に得です。しかし4行目のように縮まらない場合、費用だけがほぼ倍になります。
つまり判断は単純で、上げてみて、時間が比例して縮むかを測る。縮むなら上げる価値があり、縮まないなら戻す。これが最も確実な方法です。理屈で予測しようとすると、読み取り量・並び順・同時実行など変数が多すぎて当たりません。1回試すほうが、議論するより速く確実です。
この判断は理屈で決めるより試すほうが速い領域です。1段階上げて代表的な処理を流し、所要時間を比べる。数分で終わり、判断材料としては十分です。
2. 縮まない理由
サイズを上げても縮まないなら、計算能力が ではないということです。原因は概ね次のどれかです。
| 原因 | 症状 | 対処 |
|---|---|---|
| 処理が小さすぎる | 元々数秒で終わる | サイズは関係ない。起動時間の設計へ |
| 読み取り量が支配的 | 読んだデータ量が大きい | を効かせる(EP.5) |
| 分割できない処理 | 1つの塊として処理される | 処理の書き方を見直す |
| 外部への書き出しが遅い | 取り出し側が細い | サイズではなく経路の問題 |
2行目が最も多い原因です。読む量が減らない限り、計算資源を増やしても限界があります。この場合はサイズではなく、読み飛ばしを効かせる方向(EP.5)が正しい打ち手になります。これは パフォーマンスチューニング実践 EP.02 で扱った「計算しているのか、待っているのか」という切り分けと同じ構造です。計算資源が ボトルネック でないなら、そこを増やしても全体は動きません。
逆に、サイズを上げるべき明確な兆候もあります。 の発生です。処理中のデータがメモリに収まらずディスクへ書き出されている状態で、これが起きると急激に遅くなります。
SELECT query_id, LEFT(query_text, 60) AS クエリ, warehouse_size AS サイズ, bytes_spilled_to_local_storage / 1024 / 1024 AS ローカル書出MB, bytes_spilled_to_remote_storage / 1024 / 1024 AS リモート書出MB, total_elapsed_time / 1000 AS 秒FROM snowflake.account_usage.query_historyWHERE start_time >= DATEADD(day, -7, CURRENT_TIMESTAMP()) AND bytes_spilled_to_local_storage > 0ORDER BY bytes_spilled_to_remote_storage DESC, bytes_spilled_to_local_storage DESCLIMIT 20;リモートへの書き出しが出ていたら、明確にサイズ不足です。ここはサイズを上げれば直り、しかも所要時間が大きく縮むため、費用も下がることが多い。サイズを上げて安くなる数少ないケースです。
3. サイズを上げるのか、数を増やすのか
混同しやすいのがここです。サイズは1件の処理を速くするもの、数は同時に捌ける量を増やすものです。症状が違えば打ち手も違います。
| 症状 | 原因 | 打ち手 |
|---|---|---|
| 1件が遅い(他に誰もいなくても遅い) | 処理そのものが重い | サイズを上げる |
| 混む時間帯だけ遅い | 順番待ちが発生している | で数を増やす |
| 特定の用途だけ遅い | 他の用途と資源を奪い合っている | ウェアハウスを分ける |
2行目に対してサイズを上げても、あまり効きません。1件あたりは速くなりますが、同時に走れる数は増えないためです。待ち行列の長さは、捌ける数を増やすことでしか解消しません。
SELECT warehouse_name AS ウェアハウス, COUNT(*) AS 実行数, ROUND(AVG(queued_overload_time) / 1000, 2) AS 平均待ち秒, ROUND(MAX(queued_overload_time) / 1000, 2) AS 最大待ち秒, ROUND(AVG(execution_time) / 1000, 2) AS 平均実行秒FROM snowflake.account_usage.query_historyWHERE start_time >= DATEADD(day, -7, CURRENT_TIMESTAMP())GROUP BY warehouse_nameHAVING AVG(queued_overload_time) > 0ORDER BY 平均待ち秒 DESC;待ち時間が実行時間に対して無視できないなら、数を増やす対象です。待ちがほぼゼロなのに遅いなら、サイズか処理内容の問題になります。この2つを取り違えると、費用だけ増えて改善しません。
4. 用途で分ける
全員が1つのウェアハウスを共有していると、設計そのものができなくなります。止めてよい時間帯も、求める応答速度も、用途ごとに違うためです。
| 用途 | 求めるもの | 止め方 | サイズの考え方 |
|---|---|---|---|
| 分析・BI | 応答の速さ | 短時間で止める | 小さめ。同時実行に備えて数を |
| バッチ・変換 | 総処理時間 | 終わったら止める | スピルが出ない大きさ |
| 外部連携 | 確実に終わること | 処理時に起動 | 小さめで十分なことが多い |
| アドホック調査 | 自由に触れること | 短めに止める | 小さめ。上限を設ける |
4行目には注意が必要です。調査用途は、費用が想定外に膨らむ最大の要因になります。大きなサイズを与えると、うっかり全件走査したときの費用が跳ねます。小さめにして、必要なときだけ上げる運用にしておくと事故が減ります。小さいウェアハウスで重い処理を流せば、遅くて気づくという副次的な効果もあります。気づけること自体が安全装置として働くわけです。
1つのウェアハウスに全部載せると、誰が何にいくら使ったかが分からなくなります。EP.3 で扱いますが、用途で分けること自体が、費用可視化の前提になります。
5. 決めたら記録する
サイズと分割の方針は、根拠を残さないと必ず崩れます。誰かが「遅いから」と上げ、誰も戻さない、という形で。
- 1そのサイズにした根拠 — 測って比較した結果
- 2分けた理由 — どの用途と干渉させたくないのか
- 3止め方の設定と、その根拠 — EP.4 で扱う
- 4見直す条件 — 「待ち時間が○秒を超えたら」
4番目があると、上げっぱなしを防げます。条件を書いておけば、それが満たされたときに動けばよく、常時気にする必要がなくなります。逆にこれが無いと、一度上げたサイズは誰も下げる根拠を持てないまま残り続けます。上げるのは簡単で、下げるには勇気が要るためです。
サイズを上げても、時間が比例して縮めば総額は変わらない。縮むかは試して測るのが最速。スピル が出ていたら明確にサイズ不足で、上げて安くなるケース。1件が遅い=サイズ、混むと遅い=数、用途で遅い=分ける。分けることは費用可視化の前提でもあります。
この記事の感想を教えてください
あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。