検索最適化サービスの使用

検索最適化サービスにより、ポイントルックアップクエリのパフォーマンスを大幅に向上させることができます。

このトピックの内容:

検索最適化サービスについて

検索最適化サービスは、テーブルでの選択的ポイントルックアップクエリのパフォーマンスを大幅に向上させることを目的としています。ポイントルックアップクエリは、1つまたは少数の異なる行のみを返します。使用例は次のとおりです。

  • 非常に選択的なフィルターを備えた重要なダッシュボードにおいて、高速な応答時間を必要とするビジネスユーザー。

  • 大量のデータを探索し、データの特定のサブセットを探しているデータサイエンティスト。

ユーザーは、1つ以上のテーブルを検索最適化サービスに登録できます。検索最適化はテーブルレベルのプロパティであり、サポートされているデータ型を持つすべての列に適用されます(以下のサポートされているデータ型のリストを参照)。

検索最適化サービスが機能する方法

ポイントルックアップのパフォーマンスを向上させるために、検索最適化サービスは、最適化された検索アクセスパスとして機能する永続的なデータ構造に依存しています。

バックグラウンドで実行されるメンテナンスサービスが、検索アクセスパスの作成と保守を担当します。

  • 検索最適化をテーブルに追加すると、メンテナンスサービスは、検索を実行するために必要なデータを検索アクセスパスに作成して設定します。

    テーブルのサイズによっては、データの入力プロセスに時間がかかる場合があります。サービスはこれをバックグラウンドで実行し、テーブルにおけるいずれの同時操作も阻害しません。

  • テーブル内のデータが更新されると(たとえば、新しいデータセットのロードや DML 操作によって)、メンテナンスサービスは自動的に検索アクセスパスを更新し、データへの変更を反映します。

    検索アクセスパスがまだ更新されていないときにクエリを実行すると、クエリの実行が遅くなる可能性がありますが、常に最新の結果が返されます。

この検索アクセスパスとメンテナンスサービスは、ユーザーに対して透過的です。検索アクセスパスを維持するサービスのウェアハウスを作成する必要はありません。

ただし、このサービスのストレージおよびコンピューティングリソースにはコストがかかることに注意してください。詳細については、 検索最適化サービスのコストの管理 (このトピック内)をご参照ください。

クエリのパフォーマンスを最適化するための他のソリューションの検討

検索最適化サービスは、クエリのパフォーマンスを最適化するさまざまな方法の1つです。関連するテクニックは次のとおりです。

  • テーブルのクラスタリング。

  • 1つ以上のマテリアライズドビュー(クラスター化または非クラスター化)を作成します。

それぞれには異なる利点があります。

  • テーブルをクラスタリングすると、クラスタリングキー上にある限り、次のいずれかを高速化できます。

    • 範囲検索。

    • 等価検索。

    ただし、テーブルは単一のキー(1つ以上の列または式を含むことができる)でのみクラスター化できます。

  • 検索最適化サービスは、等価検索のみを高速化します。ただし、これは、検索最適化が有効になっているテーブルでサポートされているタイプのすべての列に適用されます。

  • マテリアライズドビューは、等価検索と範囲検索の両方、および一部のソート操作を高速化しますが、高速化は、マテリアライズドビューに含まれる行と列のサブセットに対してのみです。マテリアライズドビューは、同じソーステーブル(またはそのテーブルのサブセット)に異なるクラスタリングキーを定義するために使用したり、フラット化 JSON /バリアントデータと組み合わせて使用したりすることもできます。

次の表は、これらの3つの最適化のうちどれがストレージまたはコンピューティングコストを持つかを示しています。

ストレージコスト

コンピューティングコスト

検索最適化サービス

マテリアライズドビュー

テーブルのクラスタリング

検索最適化サービスに必要なアクセス制御権限

テーブルの検索最適化を追加または削除するには、次の権限が必要です。

  • テーブルに対する OWNERSHIP 権限が必要。

  • テーブルを含むスキーマに対する ADD SEARCH OPTIMIZATION 権限が必要。

    GRANT ADD SEARCH OPTIMIZATION ON SCHEMA <schema_name> TO ROLE <role>;
    

クエリに検索最適化サービスを使用するには、テーブルに対する SELECT 権限が必要。

その他の追加の権限は必要ありません。検索最適化はテーブルプロパティであるため、テーブルのクエリ時に自動的に検出され、(適切な場合は)使用されます。

検索最適化から恩恵を受けるテーブルの特定

検索最適化サービスは、特定のクエリタイプのパフォーマンスを向上させるように設計されています。次のセクションでは、検索最適化によりメリットが得られるクエリのテーブルとタイプを識別する方法について説明します。

検索最適化によるメリットを受けるクエリ

次の条件が当てはまる場合、検索最適化はクエリのパフォーマンスを改善するために最適に機能します。

  • クエリされるテーブルの場合、

    • 次のいずれかが当てはまります。

      • テーブルはクラスター化されていません。

      • テーブルは主クラスターキー以外の列で頻繁にクエリされます。

  • 次のクエリ:

    • 通常、クエリは少なくとも数十秒間実行されます。

    • クエリフィルター操作を通じてアクセスされる列の少なくとも1つには、少なくとも100k〜200k個の個別の値があります。

      個別の値の数を決定するには、次のいずれかを使用できます。

      • APPROX_COUNT_DISTINCT を使用して、個別の値の概算数を取得します。

        select approx_count_distinct(column1) from table1;
        
      • COUNT(DISTINCT <列名>) を使用して、個別の値における実際の数を取得します。

        select count(distinct c1), count (distinct c2)  from test_table;
        

      個別の値の概算数のみが必要なため、 COUNT(DISTINCT <列名>) より高速で安価な APPROX_COUNT_DISTINCT の使用を検討してください。

    • クエリは次の種類の述語を使用します。

      • 等価述語(たとえば、 <列名> = <定数>)。

      • IN を使用する述語( を参照)。

    • 述語の論理積(つまり、AND)を使用するクエリでは、いずれかの述語が上記の条件に準拠している場合、検索最適化によってクエリのパフォーマンスが改善します。

      たとえば、クエリに次のようなものがあるとします。

      where condition_x and condition_y

      いずれかの条件が個別に数行を返す場合(つまり、 condition_x が数行を返す、 または condition_y が数行を返す場合)は、検索最適化によってパフォーマンスが改善します。

      condition_x は数行を返すが、 condition_y は多くの行を返す場合は、検索最適化によってクエリのパフォーマンスが向上する場合があります。

      これらの追加の例 をご参照ください。

    • 述語の論理和を使用するクエリ(つまり、OR)では、 すべての 述語が上記の条件に準拠している場合、検索最適化によってクエリのパフォーマンスが改善します。

      たとえば、クエリに次のようなものがあるとします。

      where condition_x or condition_y

      各条件が個別に数行を返す場合(つまり、 condition_x が数行を返し、 加えて condition_y が数行を返す場合)は、検索最適化によってパフォーマンスが改善します。

      condition_x は数行を返すが、 condition_y は多くの行を返す場合、検索最適化によってはクエリのパフォーマンスは向上 しません

      論理和の場合、分離された各述語はクエリ内で決定的にはなりません。他の述語は、検索最適化によってパフォーマンスが改善するかどうかを判断する前に評価する必要があります。

    • 論理積と論理和(つまり、 AND と OR)を使用するクエリの場合、検索最適化サービスは、 AND がトップレベルにある場合にのみ、パフォーマンスが改善します。

      たとえば、検索最適化サービスは、次のようにしてクエリのパフォーマンスを改善できます。

      WHERE a = 1 AND (b = 2 OR c = 3)

      しかし次とは異なります。

      WHERE a = 1 OR (b = 2 AND c = 3)

検索最適化が結合に与える影響

検索最適化サービスにより、小さなテーブルを大きなテーブルと結合するクエリのパフォーマンスを改善できます。詳細については、 結合のパフォーマンスを改善する検索最適化サービスの有効化 をご参照ください。

検索最適化がビューに与える影響

検索最適化サービスにより、ビュー(セキュアビューを含む)のパフォーマンスを間接的に改善できます。ビューのベーステーブルで検索最適化が有効になっていて、クエリがそのテーブルに選択的述語を使用している場合、検索最適化サービスは、行をフィルタリングするときのパフォーマンスを改善できます。

ビュー内のすべてのテーブルで検索最適化を有効にする必要はありません。検索の最適化は、各テーブルで個別に実行されます。

検索最適化サービスの現在の制限

検索最適化サービスでは、次をサポートしていません。

  • 外部テーブル。

  • マテリアライズドビュー。

  • COLLATE 句 で定義された列。

  • 列の連結。

  • 分析表現。

  • 行アクセスポリシー で保護されているテーブルとビューは、検索最適化サービスと併用できません。

  • テーブル列にキャストします(文字列にキャストされる固定小数点数を除く)。

    検索最適化は、定数値に対する暗黙的および明示的キャストを使用した述部をサポートしていますが、実際のテーブル列に値をキャストする述部はサポートしていません(INTEGER および NUMBER から VARCHAR へのキャストを除く)。

    たとえば、次の述語は、定数値(テーブル列の値ではない)に対して暗黙的および明示的なキャストを使用するため、サポートされています。

    -- Supported predicate
    -- (where the string '2020-01-01' is implicitly cast to a date)
    WHERE timestamp1 = '2020-01-01';
    
    
    -- Supported predicate
    -- (where the string '2020-01-01' is explicitly cast to a date)
    WHERE timestamp1 = '2020-01-01'::date;
    

    次の述語は、テーブル列の値に対するキャストを使用するため、サポートされていません。

    -- Unsupported predicate
    -- (where values in a VARCHAR column are cast to DATE)
    WHERE to_date(varchar_column) = '2020-01-01';
    

    検索最適化サービスは、キャスト後の値ではなく、元の列の値を考慮します。その結果、検索最適化サービスは、これらの述語を持つクエリには使用されません。

前述のように、このルールの例外は、テーブル列の NUMBER または INTEGER 値を VARCHAR 値にキャストする場合です。検索最適化サービスは、このタイプの述語をサポートします。

-- Supported predicate
-- (where values in a numeric column are cast to a string)
WHERE cast(numeric_column as varchar) = '2'

検索最適化はアクティブなデータに対してのみ機能するため、Time Travelを使用するクエリのパフォーマンスは、検索最適化によっては向上しません。

クエリアクセラレーションサービス は、検索最適化サービスが有効になっているテーブルのクエリを高速化しません。

検索最適化サービスでサポートされているデータ型

検索最適化サービスは現在、次のデータ型に対する等価述語と IN リストの述語をサポートしています。

  • 固定小数点数(例: INTEGER、NUMERIC)

  • DATE、 TIME、 TIMESTAMP

  • VARCHAR

  • BINARY

現在、検索最適化サービスは、浮動小数点データ型、半構造化データ型、または上記以外のデータ型をサポートしていません。Snowflakeには、将来さらに多くのデータ型のサポートが追加される可能性があります。

検索最適化サービスも照合をサポートしていません。

テーブルへの検索最適化の追加

注釈

大きなテーブル(テラバイト(TB)以上のデータを含むテーブル)に検索最適化を追加すると、短期間にクレジット消費量が即座に増加する可能性があります。

テーブルに検索最適化を追加すると、メンテナンスサービスは、すぐにバックグラウンドでテーブルの検索アクセスパスの構築を開始します。テーブルが大きい場合、メンテナンスサービスがこの作業を大規模に並列化する可能性があり、その結果、短期間にコストが増加する可能性があります。

大きなテーブルに検索最適化を追加する前に、 これらのコストの見積もりを取得 して、何が起きるかを把握します。

テーブルに検索最適化を追加するには、次のステップに従います。

  1. テーブルに検索最適化を追加する権限 を持つロールに切り替えます。

  2. 次のコマンドを実行します。

    ALTER TABLE [IF EXISTS] <table_name> ADD SEARCH OPTIMIZATION;
    

    ここで、 table_name は、検索最適化を追加するテーブルの名前です。

    例:

    alter table test_table add search optimization;
    

    詳細については、 ALTER TABLE にある検索最適化のセクション をご参照ください。

  3. SHOW TABLES コマンドを実行して、検索最適化が追加されていることを確認し、テーブルがどの程度最適化されているかを判断します。

    例:

    SHOW TABLES LIKE '%test_table%';
    

    このコマンドの出力により、

    • SEARCH_OPTIMIZATION が ON であることを確認します。これは、検索最適化が追加されたことを示しています。

    • SEARCH_OPTIMIZATION_PROGRESS の値を確認します。これは、これまでに最適化されたテーブルの割合を指定します。

      検索最適化が最初にテーブルに追加されたとき、パフォーマンスの利点はすぐには現れません。検索最適化サービスは、バックグラウンドでデータの入力を開始します。メンテナンスがテーブルの現在の状態に追いつくにつれて、利点の増加が明らかになります。

      クエリを実行して検索最適化が機能していることを確認する前に、テーブルが完全に最適化されたことを示すまで待ちます。

  4. クエリを実行して、検索最適化が機能していることを確認します。

    Snowflakeオプティマイザーは、特定のクエリに対して検索最適化サービスをいつ使用するかを自動的に選択することに注意してください。ユーザーは、どのクエリ検索最適化を使用するかについては制御できません。

    検索最適化サービスが最適化するように設計されているクエリを選択します。 検索最適化から恩恵を受けるテーブルの特定 をご参照ください。

  5. ウェブ UI で、このクエリのクエリプランを表示し、クエリノード「検索最適化アクセス」がクエリプランの一部であることを確認します。

結合のパフォーマンスを改善する検索最適化サービスの有効化

注釈

この機能は、さまざまなリージョンでロールアウトされています。この機能が有効になっているリージョンのリストについては、 機能のロールアウト: 検索最適化サービスでの結合のサポート をご参照ください。

検索最適化サービスにより、小さなテーブルを大きなテーブルと結合するクエリのパフォーマンスを改善できます。

たとえば、 product は各製品の行が含まれるテーブルであり、 sales は製品の各販売の行を含むテーブルであるとします。 product の行数は少なく、 sales よりも小さくなります。特定の製品の売上すべてを確認するには、 sales テーブル(大きい方のテーブル)を product テーブル(小さい方のテーブル)と結合します。検索最適化サービスにより、この型の結合のパフォーマンスを改善できます。

注釈

データウェアハウジングでは、大きなテーブルは ファクトテーブル と呼ばれることがよくあります。小さなテーブルは ディメンションテーブル と呼ばれます。このトピックの残りの部分では、結合内の大きなテーブルと小さなテーブルを参照するときにこれらの用語を使用します。

検索最適化サービスを有効にして結合のパフォーマンスを改善するには、ファクトテーブル(2つあるテーブルのうちの大きい方)に 検索最適化を追加 します。

検索の最適化を利用するには、ディメンションテーブル(2つあるテーブルのうちの小さい方)に個別の値がほとんどないようにする必要があります。クエリの検索最適化コストは、ファクトテーブルで検索する必要がある個別の値の数に比例します。ディメンションテーブル内にある個別の値の数が多すぎる場合、Snowflakeは検索アクセスパスを使用しないことを決定し、代わりに通常のテーブルアクセスパスを使用する可能性があります。

サポートされている結合述語

検索最適化サービスにより、次の型の結合述語を使用してクエリのパフォーマンスを改善できます。

  • dimension_table.column = fact_table.column 形式の等値述語。

  • ディメンションのある述語側の変換(例: 文字列の連結、追加など)。

  • 複数の等価述語の結合(AND)。

サポートされている結合使用クエリの例

このセクションでは、結合を使用した検索最適化によりメリットを受けるクエリの例を示します。

例: 結合述語としての単純な等価述語

以下は、単純な等価述語を結合述語として使用する、サポートされているクエリの例です。このクエリは、 sales という名前のファクトテーブルを product という名前のディメンションテーブルと結合します。ファクトテーブルが大きく、検索最適化が有効になっています。 category 列の選択フィルターにより、ディメンションテーブルからの入力は小さくなります。

SELECT sales.date, product.name
FROM sales JOIN product ON (sales.product_id = product.id)
WHERE product.category = 'Cutlery';

例: ディメンション側で変換された結合述語

ディメンションのある述語側で変換するクエリ(乗算など)も、検索最適化のメリットを受けることができます。

SELECT sales.date, product.name
FROM sales JOIN product ON (sales.product_id = product.old_id * 100)
WHERE product.category = 'Cutlery';

例: 複数の列にまたがる結合述語

結合述語が複数の列にまたがるクエリもサポートされています。

SELECT sales.date, product.name
FROM sales JOIN product ON (sales.product_id = product.id and sales.location = product.place_of_production)
WHERE product.category = 'Cutlery';

例: ポイントルックアップフィルターと結合述語を使用したクエリ

通常のポイントルックアップフィルターと結合述語の両方を使用するクエリでは、検索最適化サービスにより両方のパフォーマンスを改善できます。次のクエリでは、検索最適化サービスにより sales.location ポイントルックアップ述語と product_id 結合述語を改善します。

SELECT sales.date, product.name
FROM sales JOIN product ON (sales.product_id = product.id)
WHERE product.category = 'Cutlery'
AND sales.location = 'Buenos Aires';

結合のサポートの制限

  • 結合述語の論理和(OR)は現在サポートされていません。

  • LIKE/ILIKE/RLIKE 結合述語は現在サポートされていません。

  • バリアント列の結合述語は現在サポートされていません。

  • EQUAL_NULL 等価述語はサポートされません。

  • 検索最適化サービスの現在の制限 もこの機能に適用されます。

検索最適化サービスのコストの管理

検索最適化サービスは、ストレージリソースとコンピューティングリソースの両方のコストに影響します。

  • ストレージリソース:検索最適化サービスにより、検索アクセスパスデータ構造を作成します。この構造には、検索最適化が有効になっている各テーブルにスペースが必要です。検索アクセスパスのストレージコストは、次のような複数の要因によって異なります。

    • テーブル内における個別の値の数(NDVs)。すべての列に検索アクセスパスを使用するデータ型があり、各列のすべてのデータ値が一意であるという極端な場合、必要なストレージは元のテーブルのサイズと同じ程度の大きさになる可能性があります。

      ただし、通常、サイズは元のテーブルのサイズの約1/4です。

  • コンピューティングリソース:

    • テーブルに検索最適化を追加すると、リソースが消費されます。

    • 検索最適化サービスを維持するには、リソースも必要です。チャーンが多い場合(つまり、テーブル内で大量のデータが変更される場合)は、リソースの消費量が多くなります。これらのコストは、取り込まれた(追加または変更された)データの量にほぼ比例します。削除にもいくらかのコストがかかります。

      Snowflakeは、実際に使用されたリソースに対してのみアカウントに請求することにより、効率的なクレジット使用状況を確保します。請求は1秒単位で計算されます。

      コンピューティング時間あたりのコストについては、 Snowflakeサービス利用テーブル の「サーバーレス機能クレジットテーブル」をご参照ください。

      検索最適化サービスを有効にすると、 サービスの使用料金を表示 できます。

ちなみに

Snowflakeは、この機能を徐々に始めて(最初は検索最適化をいくつかのテーブルのみに追加するなど)、コストと利点を注意深く監視することをお勧めします。

コストの見積もり

テーブルに検索最適化を追加するためのコストを見積もるには、 SYSTEM$ESTIMATE_SEARCH_OPTIMIZATION_COSTS 関数を使用します。

一般的に、コストは次の要素に比例します。

  • この機能が有効になっているテーブルの数、およびそれらのテーブル内の個別の値の数。

  • これらのテーブルで変更されるデータの量。

コストの表示

ウェブインターフェイスまたは SQL を使用して、検索最適化サービスの請求コストを表示できます。 サーバーレス機能の請求について をご参照ください。

コストの削減

慎重に 検索最適化を有効にするテーブルを選択する ことにより、検索最適化サービスのコストを制御できます。

さらに、検索最適化サービスのコストを削減するには、

  • SnowflakeはテーブルでDML操作をバッチ処理することをお勧めします。

    • DELETE :テーブルに最新の期間(例:最新の日、週、月)のデータが保存されている場合は、古いデータを削除してテーブルをトリミングする際に、検索最適化サービスで変更を考慮する必要があります。場合によっては、削除の頻度を減らすことでコストを削減できる場合があります(例: 1時間ごとではなく1日ごと)。

    • INSERTUPDATE、および MERGE :これらのタイプの DML ステートメントをテーブルでバッチ処理すると、検索最適化サービスにより、メンテナンスのコストを削減できます。

  • テーブル全体を再クラスター化する場合は、再クラスタリングする前にそのテーブルの 検索最適化プロパティ を削除し、再クラスタリング後に検索最適化サービスを再度追加することを検討してください。

テーブルからの検索最適化プロパティの削除

テーブルから検索最適化プロパティを削除するには、

  1. テーブルから検索最適化を削除する権限 があるロールに切り替えます。

  2. 次のコマンドを実行します。

    ALTER TABLE [IF EXISTS] <table_name> DROP SEARCH OPTIMIZATION;
    

    例:

    alter table test_table drop search optimization;
    

    詳細については、 ALTER TABLE にある検索最適化のセクション をご参照ください。

次のコードは、検索最適化サービスの作成と使用を示しています。

データがあるテーブルの作成から始めます。

create or replace table test_table (id int, c1 int, c2 string, c3 date) as
select * from values
  (1, 3, '4',  '1985-05-11'),
  (2, 4, '3',  '1996-12-20'),
  (3, 2, '1',  '1974-02-03'),
  (4, 1, '2',  '2004-03-09'),
  (5, null, null,  null);

テーブルに検索最適化プロパティを追加します。

alter table test_table add search optimization;

次のクエリでは、検索最適化サービスを使用できます。

select * from test_table where id = 2;
select * from test_table where c2 = '1';
select * from test_table where c3 = '1985-05-11';
select * from test_table where c1 is null;
select * from test_table where c1 = 4 and c3 = '1996-12-20';

次のクエリでは、暗黙的なキャストが列ではなく定数に対して行われるため、検索最適化を使用できます。

select * from test_table where c2 = 2;

次のキャストはテーブルの列にあるため、検索最適化を使用 できません

select * from test_table where cast(c2 as number) = 2;

IN 句は検索最適化と互換性があります。

select id, c1, c2, c3
    from test_table
    where id IN (2, 3)
    order by id;

それぞれの述語が検索最適化と個別に互換性がある場合は、論理積 AND によって結合でき、結合後も検索最適化との互換性を維持できます。

select id, c1, c2, c3
    from test_table
    where c1 = 1
       and
          c3 = TO_DATE('2004-03-09')
    order by id;

DELETE および UPDATE (および MERGE)も、検索最適化サービスを使用することができます。

delete from test_table where id = 3;
update test_table set c1 = 99 where id = 4;
最上部に戻る