ScaNN インデックスのチューニングに関するベスト プラクティス

ドキュメントのバージョンを選択してください。

効果的な手法に沿って ScaNN インデックスをチューニングし、検索の再現率と秒間クエリ数(QPS)のバランスを取ります。インデックスのレベル数に応じて、推奨されるパラメータと値が異なります。

ScaNN インデックスの作成については、ScaNN インデックスを作成するをご覧ください。

上限

ScaNN インデックスのチューニングを開始する前に、次の上限を確認してください。

  • num_leaves は 3,000 万に制限されます。

始める前に

4 レベルの ScaNN インデックスを作成する場合は、まず AlloyDB インスタンスのプレビュー機能を有効にする必要があります。プレビュー機能を有効にするには、次のいずれかの方法を選択します。

2 レベル ツリー インデックス

推奨事項を適用して、データセットに最適な num_leavesnum_leaves_to_search の値を見つけるには、次の推奨手順に沿って操作します。

  1. 次のケースに最適化された ScaNN インデックスを作成するには、num_leaves パラメータを次の値に設定します。ここで、「rows」はインデックス付きテーブルの行数です。
    • インデックスのビルド時間と品質のバランスを取るには、num_leavessqrt(rows) に設定します。
    • 品質を重視するには、num_leaves を rows/100 に設定します。
  2. 目標とする再現率の範囲(95% など)に達するまで、テストクエリを実行し、scann.num_of_leaves_to_search の値を増やします。クエリの分析の詳細については、クエリを分析するをご覧ください。
  3. scann.num_leaves_to_searchnum_leaves の比率は、以降のステップで使用するのでメモしておきます。この比率は、目標の再現率を達成するために役立つデータセットの近似値を提供します。

    高次元ベクトル(500 次元以上)を扱っていて、再現率を改善したい場合は、scann.pre_reordering_num_neighbors の値をチューニングしてみてください。デフォルト値は 50 * K に設定されています。ここで、K はクエリで設定した上限です。
  4. クエリによって目標の再現率が達成された後、QPS が低すぎる場合は、次の操作を行います。
    1. インデックスを再作成し、次のガイダンスに従って num_leavesscann.num_leaves_to_search の値を増やします。
      • num_leaves を、行数の平方根に対するより大きな係数に設定します。たとえば、インデックスの num_leaves が行数の平方根に設定されている場合は、平方根の 2 倍に設定してみてください。値がすでに 2 倍になっている場合は、平方根の 3 倍に設定してみてください。
      • 必要に応じて scann.num_leaves_to_search を増やし、ステップ 3 でメモした num_leaves との比率を維持します。
      • num_leaves は、行数を 100 で除した値以下の値に設定します。
    2. テストクエリをもう一度実行します。テストクエリを実行しながら、scann.num_leaves_to_search を減らしてみて、高い再現率を維持しつつ QPS を高める値を見つけます。インデックスを再ビルドせずに、scann.num_leaves_to_search の値を変更してみてください。
  5. QPS と再現率の範囲の両方が許容値に達するまで、手順 4 を繰り返します。

3 レベル ツリー インデックス

2 レベルツリーの ScaNN インデックスに関する推奨事項に加えて、次のガイダンスを使用してください。

推奨事項を適用して、num_leaves インデックス パラメータと max_num_levels インデックス パラメータの最適な値を見つける手順は、次のとおりです。

  1. パフォーマンス目標に基づき、次の num_leavesmax_num_levels を組み合わせて ScaNN インデックスを作成します。

    • インデックスのビルド時間と品質のバランスを取る: max_num_levels2 に、num_leavespower(rows, ⅔) に設定します。
    • 品質重視で最適化: max_num_levels2 に、num_leavesrows/100 に設定します。
  2. テストクエリを実行します。クエリの分析の詳細については、クエリを分析するをご覧ください。

  3. scann.num_leaves_to_searchnum_leaves の比率は、以降のステップで使用するのでメモしておきます。この比率は、目標の再現率の達成に役立つデータセットの近似値を提供します。

高次元ベクトル(500 次元以上)を扱っていて、再現率を改善したい場合は、scann.pre_reordering_num_neighbors の値をチューニングしてみてください。デフォルト値は 50 * K に設定されています。ここで、K はクエリで設定した上限です。

  1. クエリによって目標の再現率が達成された後、QPS が低すぎる場合は、次の操作を行います。

    • インデックスを再作成し、次のガイダンスに従って num_leavesscann.num_leaves_to_search の値を増やします。
    • num_leaves を、power(rows, ⅔) に対するより大きな係数に設定します。たとえば、インデックスの num_leavespower(rows, ⅔) に設定されている場合は、power(rows, ⅔) の 2 倍に設定してみてください。値がすでに 2 倍になっている場合は、power(rows, ⅔) の 3 倍に設定してみてください。
    • 必要に応じて scann.num_leaves_to_search を増やし、ステップ 3 でメモした num_leaves との比率を維持します。
    • num_leavesrows/100 以下の値に設定してください。
    • テストクエリをもう一度実行します。テストクエリを実行しながら、scann.num_leaves_to_search を減らしてみて、高い再現率を維持しつつ QPS を高める値を見つけます。インデックスを再ビルドせずに、scann.num_leaves_to_search の値を変更してみてください。
  2. QPS と再現率の範囲の両方が許容値に達するまで、手順 4 を繰り返します。

4 レベル ツリー インデックス

3 レベル ツリー インデックスに関する推奨事項に加えて、次のガイダンスを使用して num_leavesmax_num_levels の最適な値を見つけます。

  1. パフォーマンス目標に基づき、次の num_leavesmax_num_levels を組み合わせて ScaNN インデックスを作成します。

    • インデックスのビルド時間と品質のバランスを取る: max_num_levels3 に、num_leavespower(ROWS, 3/4) に設定します。

    • 品質重視で最適化: max_num_levels3 に、num_leavesROWS/100 に設定します。

  2. テストクエリを実行します。クエリの分析の詳細については、クエリを分析するをご覧ください。

  3. scann.num_leaves_to_searchnum_leaves の比率をメモしておきます。この比率を使用して、以降のステップで目標再現率を達成します。

    高次元ベクトル(500 次元以上)を扱っていて、再現率を改善したい場合は、scann.pre_reordering_num_neighbors の値をチューニングしてみてください。

  4. クエリによって目標の再現率が達成された後、QPS が低すぎる場合は、次のガイダンスに従って num_leavesscann.num_leaves_to_search の値を増やしてインデックスを再作成します。

    1. num_leaves を、power(ROWS, 3/4) に対するより大きな係数に設定します。たとえば、インデックスの num_leavespower(ROWS, 3/4) に設定されている場合は、その 2 倍に設定してみてください。値がすでに 2 倍になっている場合は、3 倍に設定してみてください。

    2. 必要に応じて scann.num_leaves_to_search を増やし、ステップ 3 でメモした num_leaves との比率を維持します。

    3. num_leavesROWS/100 以下の値に設定してください。

    4. テストクエリをもう一度実行します。テストクエリを実行しながら、scann.num_leaves_to_search を減らしてみて、高い再現率を維持しつつ QPS を高める値を見つけます。インデックスを再ビルドせずに、scann.num_leaves_to_search の値を変更してみてください。

  5. 再現率の範囲と QPS の両方が許容値に達するまで、手順 4 を繰り返します。

フィルタされた検索の再現率を高める

フィルタ付きの k 近傍法(KNN)ベクトル検索を行うと、LIMIT 句でリクエストした数の結果よりも少ない件数しか返ってこないことがあります。これは再現率の不足と呼ばれる問題を引き起こす可能性があり、フィルタが厳しい場合に特に発生しやすくなります。この現象が起こる理由は、ScaNN が最初に検索するパーティションやリーフに、フィルタ条件を満たすベクトルが十分に含まれていないためです。

この問題に対処するために、AlloyDB Omni には、検索を最初のリーフセットを超えて動的に拡張し、十分な一致結果を見つけることができる機能が用意されています。

ストリーミングの仕組み

scann.satisfy_limit パラメータを relaxed_order に設定することで、ストリーミング機能を有効にできます。この機能を有効にすると、ベクトル スキャンはクエリの LIMIT を満たすのに十分な結果が見つかるまで追加のリーフ パーティションの検索を続行し、再現率を高めます。

検索が長時間継続するのを防ぎ、パフォーマンスへの影響を制御するには、scann.max_pct_leaves_to_search パラメータを使用します。この設定はセーフガードとしての役割を果たしており、クエリがアクセスできる全リーフの割合に上限を設けます。デフォルト値は 15% です。

ストリーミングを使用するケース

次の場合には、ストリーミング機能の使用を検討してください。

  • ベクトル検索でフィルタを使用している。
  • クエリが LIMIT 句で指定した件数よりも少ない結果しか返してこない。

scann.satisfy_limit を有効にすることで、フィルタ付き検索の再現率を高めることができます。さらに、再現率とクエリ パフォーマンスのバランスをとるために、scann.max_pct_leaves_to_search も構成することをおすすめします。

インデックスのメンテナンス

テーブルの更新や挿入が頻繁に発生する場合は、再現率と精度を高めるために、既存の ScaNN インデックスを定期的に再作成することをおすすめします。インデックス指標をモニタリングすることで、インデックス作成以降のベクトル分布やベクトル変異の変化を確認し、必要に応じてインデックスを再作成できます。指標の詳細については、ベクトル インデックスの指標を表示するをご覧ください。

次のステップ