Search Optimization Service(SOS)は、Snowflakeの大規模テーブルに対するポイントルックアップクエリを 劇的に高速化するサーバーレス機能です。 内部的にSearch Access Pathと呼ばれる補助データ構造を構築し、 パーティションプルーニングだけでは到達できない精度でスキャン対象を絞り込みます。Enterprise Edition以上で利用可能です。
通常のクエリ実行ではSnowflakeはマイクロパーティションのメタデータ(列の最小値・最大値)を参照してプルーニングを行います。 SOSはこれに加えて、列の値とマイクロパーティションの対応関係を記録したSearch Access Pathを構築します。 WHERE句で特定の値を検索すると、SOSのアクセスパスから該当するマイクロパーティションのみがピンポイントで特定され、 スキャン量が数桁のオーダーで削減されます。
テーブル全体に適用する場合と、特定の列・メソッドに限定する場合でSQL構文が異なります。
-- テーブル全体にSOSを有効化
ALTER TABLE analytics.customers
ADD SEARCH OPTIMIZATION;
-- 特定の列に対してメソッドを指定して有効化
ALTER TABLE analytics.customers
ADD SEARCH OPTIMIZATION ON
EQUALITY(customer_id),
EQUALITY(email),
SUBSTRING(customer_name),
EQUALITY(metadata:plan_type);
-- 特定の列のSOSを無効化
ALTER TABLE analytics.customers
DROP SEARCH OPTIMIZATION ON
SUBSTRING(customer_name);
-- テーブル全体のSOSを無効化
ALTER TABLE analytics.customers
DROP SEARCH OPTIMIZATION;
-- SOSの状態確認
DESCRIBE SEARCH OPTIMIZATION ON analytics.customers;SOSが高速化できるクエリパターンは限定的です。 以下の表は試験で問われるポイントでもあるため、正確に把握してください。
| クエリパターン | 対応メソッド | SQLの例 | 備考 |
|---|---|---|---|
| 等値検索(=) | EQUALITY | WHERE id = 12345 | 主キー検索に最適 |
| IN句 | EQUALITY | WHERE status IN ('A','B') | 複数値ルックアップ |
| 部分文字列検索 | SUBSTRING | WHERE name LIKE '%tanaka%' | 前方一致も含む |
| VARIANT / OBJECTパス検索 | EQUALITY | WHERE data:key = 'val' | 半構造化データ対応 |
| GEOGRAPHY / GEOMETRY関数 | GEO | ST_DISTANCE(geo, ...) < 1000 | 地理空間検索 |
| 範囲検索(BETWEEN / >=) | - | WHERE date BETWEEN '...' AND '...' | SOSの対象外(Clustering Keysが有効) |
SOSとClustering Keysは競合する機能ではなく、相互補完の関係にあります。
| 比較項目 | Search Optimization Service | Clustering Keys |
|---|---|---|
| 最適なクエリ | 等値/IN/部分文字列/VARIANT検索 | 範囲フィルタ(BETWEEN/>=/<=) |
| 内部構造 | Search Access Path(補助インデックス的構造) | マイクロパーティションの物理的ソート |
| メンテナンス | Serverless Credit(自動) | Automatic Clustering(Serverless Credit) |
| Edition要件 | Enterprise以上 | Enterprise以上 |
| 列の指定 | ON句で列+メソッドを個別指定可 | CLUSTER BY句で最大4列程度 |
| 併用 | 併用可能。日付列をClustering Key、ID列にSOSが典型パターン | |
SOSのメンテナンスコストはDMLの頻度に比例します。 高頻度INSERTのテーブルではコストが増大するため、定期的にモニタリングが必要です。
-- SOSのメンテナンスコスト履歴を確認
SELECT *
FROM TABLE(INFORMATION_SCHEMA.SEARCH_OPTIMIZATION_HISTORY(
DATE_RANGE_START => DATEADD('DAY', -14, CURRENT_TIMESTAMP()),
DATE_RANGE_END => CURRENT_TIMESTAMP()
));
-- ACCOUNT_USAGEからテーブル別コスト集計
SELECT
TABLE_NAME,
SUM(CREDITS_USED) AS total_credits,
COUNT(*) AS maintenance_runs
FROM SNOWFLAKE.ACCOUNT_USAGE.SEARCH_OPTIMIZATION_HISTORY
WHERE START_TIME >= DATEADD('DAY', -30, CURRENT_TIMESTAMP())
GROUP BY TABLE_NAME
ORDER BY total_credits DESC;実務でSOSを導入する際の典型的な設計パターンを示します。
SnowPro
問題 1
数十億行のトランザクションテーブルに対して、transaction_id(UUID)で頻繁に等値検索を行う必要があります。パフォーマンスを最適化するための最も適切なアプローチはどれですか?
正解: B
UUIDのようなカーディナリティが極端に高い列でのポイントルックアップにはSOSが最適です。Clustering Keysはカーディナリティが高すぎる列では効果が薄く、メンテナンスコストに見合いません。ユニーク制約は検索高速化の機能ではなく、ウェアハウスサイズの拡大はフルスキャン量自体を減らせません。
Search Optimization ServiceとClustering Keysはどう使い分けますか?
Clustering Keysはデータの物理配置を制御してパーティションプルーニングを改善する機能で、範囲フィルタ(BETWEEN / >= / <=)や等値フィルタに有効です。一方SOSは、等値検索(= / IN)、部分文字列検索(LIKE '%keyword%')、VARIANT内のパス検索、GEOGRAPHY/GEOMETRY関数に特化した補助的なアクセス構造を構築します。両者は併用可能であり、Clustering Keysでカバーしきれない検索パターンにSOSを追加するのが基本設計です。
SOSを有効にするとストレージコストは増えますか?
はい。SOSは内部的に検索アクセスパス(Search Access Path)というデータ構造を構築するため、追加のストレージコストが発生します。またDMLが実行されるたびにアクセスパスのメンテナンスが必要で、これはServerless Creditとして課金されます。SEARCH_OPTIMIZATION_HISTORYテーブル関数でメンテナンスコストの推移を確認できます。
SOSは特定の列だけに適用できますか?
はい。ALTER TABLE ADD SEARCH OPTIMIZATION ON句で対象の列とメソッド(EQUALITY / SUBSTRING / GEO)を個別に指定できます。テーブル全体に適用する場合はON句を省略しますが、不要な列にまで適用するとメンテナンスコストが増大するため、実際にクエリで使用する列のみを指定するのが推奨です。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Snowflake資格一覧|全11試験(SnowPro)の難易度・費用
Snowflake認定資格(SnowPro)全11試験の一覧・難易度・費用・出題範囲を徹底解説。...
Snowflake試験の難易度ランキング|全11資格を徹底比較
Snowflake(SnowPro)認定全11試験の難易度をランキング形式で比較。学習時間・合格に必要なスキルから分析。...
Snowflake資格の勉強方法|効率的な学習ルートと合格のコツ
Snowflake認定資格(SnowPro)に最短で合格するための勉強方法。公式リソース・学習スケジュールを徹底ガイド。...
SnowPro Core試験完全解説|出題範囲・問題例・合格戦略
SnowPro Core Certification(COF-C03)を徹底解説。出題範囲・100問の試験形式・合格ライ...
SnowPro Platform Associate完全解説|入門試験の攻略
SnowPro Associate: Platform Certification(SOL-C01)を徹底解説。最も簡単...