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

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

このトピックの内容:

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

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

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

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

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

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

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

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

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

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

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

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

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

ただし、このサービスのストレージとコンピューティングリソースにはコストがかかるため、このサービスに注意する必要があります。 検索最適化サービスのコストの管理 をご参照ください。

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

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

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

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

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

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

    • 範囲検索。

    • 等価検索。

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

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

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

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

ストレージコスト

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

検索最適化サービス

マテリアライズドビュー

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

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

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

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

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

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

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

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

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

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

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

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

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

    • テーブルサイズは100 GB 以上です。

      小さいテーブル(サイズが10 GB 未満など)の場合、検索最適化サービスによるクエリのパフォーマンスの向上は、コストに見合うほどのものではありません。

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

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

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

  • 次のクエリ:

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

    • クエリフィルター操作を通じてアクセスされる列の少なくとも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 条件X and 条件Y

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

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

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

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

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

      where 条件X or 条件Y

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

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

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

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

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

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

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

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

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

検索最適化サービスは、結合のパフォーマンスを直接改善しません。ただし、テーブルで検索最適化が有効になっていて述語が選択的である場合は、結合の前にいずれかのテーブルから行をフィルタリングするパフォーマンスを改善できます。

両方のテーブルで検索最適化を有効にする必要はありません。検索最適化を使用するかどうかの決定は、テーブルごとに個別に行われます。

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

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

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

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

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

  • 外部テーブル。

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

  • 列の連結。

  • 分析表現。

  • テーブル列へのキャスト。

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

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

    -- Supported predicate
    -- (where the numeric constant 3 is implicitly cast to a varchar)
    WHERE varchar_column = 3
    
    -- Supported predicate
    -- (where the numeric constant 3 is explicitly cast to a varchar)
    WHERE varchar_column = to_varchar(3)
    

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

    -- Unsupported 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には、将来さらに多くのデータ型のサポートが追加される可能性があります。

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

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

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

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

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

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

    例:

    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 で、このクエリのクエリプランを表示し、クエリノード「検索最適化アクセス」がクエリプランの一部であることを確認します。

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

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

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

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

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

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

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

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

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

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

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

ちなみに

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

コストの見積もり

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

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

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

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

コストの表示

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

コストの削減

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

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

  • テーブルで 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 = 1;

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

select * from test_table where cast(c1 as string) = '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;