ふくふくHukuhuku Inc.
EP.05Snowflake 14分公開: 2026-09-01

マイクロパーティションとクラスタリング ── 読み飛ばしが効く条件

索引がない代わりに、読まなくてよい塊を除外する仕組みが効きます。効く条件と効かない条件、そしてクラスタリングキーを設定すべきかの判断を扱います。

#Snowflake#パフォーマンス#設計#SQL
執筆 / 監修
松尾 亮合同会社ふくふく 代表社員

データ基盤・データパイプライン構築 / BI / 生成 AI 活用支援を専門とするエンジニア (28 年)。 本記事は AI 利用ポリシーに基づき、生成 AI の補助で執筆 → 人間が監修・編集して公開しています。

プロフィール詳細
シェア

EP.1 で触れたとおり、 には利用者が作る索引がありません。代わりに効くのが です。

この回は、効く条件と効かない条件、そして を設定すべきかの判断を扱います。性能問題の相当部分がここに帰着します。

1. 読み飛ばしの仕組み

データは自動的に区画へ分割され、各区画には含まれる値の範囲が記録されています。検索条件と突き合わせて、範囲外の区画は読まない。これだけです。

重要なのは、この効きが「データの並び順」に依存するという点です。同じ検索条件でも、データがどう配置されているかで読む量が変わります。

並び順が効きを決める
配置日付で絞ったとき読み飛ばし
日付順に並んでいる該当区画は連続して存在大きく効く
ばらばらに散っている全区画に少しずつ含まれるほぼ効かない

下の行が問題です。どの区画にも該当データが少しずつ入っていると、結局すべて読むことになります。区画の情報だけでは「含まれていない」と判断できないためです。1件だけ含まれている区画も、1万件含まれている区画も、読む必要があるという点では同じです。この「少しだけ含まれている」状態が積み重なると、実質的に全件走査になります。

取り込み順が既定の並び順になる

特に設定しなければ、取り込んだ順にデータが配置されます。日次で追加していれば日付順に並ぶため、日付での絞り込みは自然に効きます。多くの現場でクラスタリングキーが不要なのは、この既定の挙動が十分機能しているからです。

2. 効いているかを確認する

判断は必ず実測からです。クエリ履歴に読んだ区画数と全区画数が記録されています。

読み飛ばしが効いていないクエリを探す
SQL
SELECT    LEFT(query_text, 70)                              AS クエリ,    partitions_scanned                                AS 読んだ区画,    partitions_total                                  AS 全区画,    ROUND(100.0 * partitions_scanned          / NULLIF(partitions_total, 0), 1)           AS 読んだ割合,    rows_produced                                     AS 返した行,    ROUND(bytes_scanned / POWER(1024, 3), 2)          AS 読取GB,    ROUND(total_elapsed_time / 1000, 1)               ASFROM snowflake.account_usage.query_historyWHERE start_time >= DATEADD(day, -7, CURRENT_TIMESTAMP())  AND partitions_total > 100          -- 小さい表は対象外  AND rows_produced < 100000          -- 返す行は少ないのに  AND partitions_scanned > partitions_total * 0.8   -- ほぼ全部読んでいるORDER BY bytes_scanned DESCLIMIT 20;

条件が要点です。返す行は少ないのに、ほぼ全区画を読んでいるものを探しています。これが改善余地の大きいクエリです。逆に、全区画を読んでいても返す行が多いなら、それは正当な全件処理です。

3. 効かなくなる書き方

並び順が良くても、書き方によって読み飛ばしが無効になります。これは索引の話(パフォーマンスチューニング実践 EP.03)と同じ構造です。

読み飛ばしが効かなくなる書き方と、その回避
SQL
-- 効かない: 列に関数を適用しているSELECT * FROM ordersWHERE TO_DATE(created_at) = '2026-10-01';
-- 効く: 列はそのまま、範囲で指定するSELECT * FROM ordersWHERE created_at >= '2026-10-01'  AND created_at <  '2026-10-02';
-- 効きにくい: 前方一致でない文字列検索SELECT * FROM customers WHERE name LIKE '%商店%';
-- 効く: 前方一致なら範囲として扱えるSELECT * FROM customers WHERE name LIKE '田中%';

原則は単純で、区画に記録された「値の範囲」と比較できる形かどうかです。列を加工すると、その値がどの範囲に入るか判断できなくなり、全部読むしかなくなります。

書き方と読み飛ばしの関係
条件の書き方読み飛ばし理由
`col >= X AND col < Y`効く範囲として比較できる
`col = X`効く範囲に含まれるか判断できる
`col IN (X, Y, Z)`効くそれぞれ判断できる
`FUNC(col) = X`効かない加工後の値の範囲は不明
`col LIKE '%X%'`効かない先頭が不定で範囲にならない
`col != X`効かないほぼ全区画が該当しうる

4. クラスタリングキーを設定すべきか

並び順を意図的に保ちたい場合に使うのが クラスタリングキー です。ただし維持のための処理が継続的に発生し、その分の費用がかかります。設定は慎重に判断します。

  1. 1表が十分大きいか — 小さい表なら全部読んでも一瞬。効果がない
  2. 2その列で絞る検索が繰り返されるか — 一度きりの調査のためには設定しない
  3. 3現状の並び順で効いていないか — 取り込み順で足りているなら不要
  4. 4更新の頻度は高すぎないか — 頻繁に書き換わると維持費用が嵩む
  5. 5効果は維持費用を上回るか — 実測で確認する

3番目で止まることが非常に多いです。日付で絞る検索なら、取り込み順で既に効いています。あえて設定する必要があるのは、取り込み順とは別の軸で絞る場合 ── 例えば顧客IDで絞る検索が主体、といったケースです。この判断を飛ばして設定すると、効果がないのに維持費用だけを払い続ける状態になります。しかも効いていないことに気づきにくい。

更新が多い表には向かない

並び順を保つには、書き換わるたびに再配置が要ります。頻繁に更新される表では、維持費用が効果を食い潰します。追記が中心で、絞り込みの軸が明確な表 ── これが適した条件です。

5. 設定せずに済ませる方法

クラスタリングキー を設定する前に、同じ効果を別の方法で得られないかを検討する価値があります。

クラスタリングキー以外の選択肢
方法内容向く場面
取り込み順を整える投入時に並べてから入れる定期的にまとめて入れる場合
表を分ける軸ごとに別テーブルにする軸が少数に固定されている場合
事前に集計しておくよく使う粒度で別表を作る同じ集計が繰り返される場合
絞り込み条件を見直すそもそも読む範囲を減らす無条件の全件検索がある場合

3番目が実務では効きます。同じ集計が何度も走るなら、結果を持っておくほうが確実です。読み飛ばしの最適化より、読む必要そのものをなくすほうが効果が大きい。EP.4 で扱った が効く条件を整えるのも、同じ方向の打ち手です。

これは パフォーマンスチューニング実践 EP.03 で書いた「最も効く改善は、そのクエリを実行しないこと」と同じ発想です。

6. 設定したら効果を測る

設定したら、本当に効いたかを確認します。読んだ区画の割合が下がっているか、そして維持費用がどれだけ発生しているかの両方を見ます。

クラスタリング維持にかかっているクレジット
SQL
SELECT    table_name                        AS テーブル,    DATE_TRUNC('day', start_time)     AS 日付,    ROUND(SUM(credits_used), 3)       AS 維持クレジット,    SUM(num_rows_reclustered)         AS 再配置行数FROM snowflake.account_usage.automatic_clustering_historyWHERE start_time >= DATEADD(day, -30, CURRENT_TIMESTAMP())GROUP BY 1, 2ORDER BY 維持クレジット DESCLIMIT 20;

維持費用が、削減できた読み取り分を上回っていないかを確認します。上回っているなら外す判断になります。設定して終わりにすると、効いていないのに費用だけ払い続ける状態が残ります。

ここまでのまとめ

読み飛ばしの効きはデータの並び順で決まり、既定では取り込み順になる。日付での絞り込みが自然に効くのはこのため。列を加工すると効かなくなるのは索引と同じ。クラスタリングキー は取り込み順と別の軸で絞る場合に限り検討し、維持費用と効果を実測で比較する。設定前に「そもそも読まずに済ませる」選択肢も検討してください。

シェア

この記事の感想を教えてください

あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。

シリーズの外も探す:

まずは、現状を聞かせてください。

要件が固まっていなくて大丈夫です。現状診断と方針提案までを無料でお手伝いします。

無料相談フォームへ hello [at] hukuhuku [dot] co [dot] jp