効率的な上位 k 個の検索を実行する

多くのアプリケーションは、データベースにクエリを実行して、アプリケーションの 1 つのページにデータを入力します。このようなアプリケーションでは、すべての一致ではなく、インデックスの並べ替え順序に基づく上位 k 件の一致のみが必要です。検索インデックスでは、このタイプの検索を非常に効率的に実装できます。このページでは、上位 k 件の一致を含むインデックスを作成して検索する方法について説明します。

上位 k 件の一致の検索インデックスを作成する

上位 k 件の一致の検索インデックスを構成するには、ORDER BY を使用して検索インデックスを特定の列で並べ替えます。クエリには、検索インデックスの並べ替え順序(昇順と降順の方向を含む)と完全に一致する ORDER BY 句と、一致する行が k 個見つかったらクエリを停止するようリクエストする LIMIT 句が必要です。

これらの句を使用してページネーションを実装することもできます。詳細については、検索クエリをページ分けするをご覧ください。

ユースケースによっては、異なる列で並べ替えられた複数の検索インデックスを維持することが理にかなっている場合があります。パーティショニングと同様に、ストレージおよび書き込みコストと、クエリ レイテンシにはトレードオフの関係があります。

たとえば、次のスキーマを使用するテーブルについて考えてみましょう。

CREATE TABLE Albums (
  AlbumId STRING(MAX) NOT NULL,
  RecordTimestamp INT64 NOT NULL,
  ReleaseTimestamp INT64 NOT NULL,
  ListenTimestamp INT64 NOT NULL,
  AlbumTitle STRING(MAX),
  AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN
) PRIMARY KEY(AlbumId);

CREATE SEARCH INDEX AlbumsRecordTimestampIndex
ON Albums(AlbumTitle_Tokens, SingerId_Tokens)
ORDER BY RecordTimestamp DESC
STORING ListenTimestamp

CREATE SEARCH INDEX AlbumsReleaseTimestampIndex
ON Albums(AlbumTitle_Tokens)
ORDER BY ReleaseTimestamp DESC
STORING ListenTimestamp

検索インデックスに対して上位 k 個の一致をクエリする

前述のように、クエリには、検索インデックスの並べ替え順序(昇順と降順の方向を含む)と完全に一致する ORDER BY 句と、k 個の一致する行が見つかったらクエリを停止するようリクエストする LIMIT 句が必要です。

一般的なクエリには、次のものがあります。

  • 次のクエリは非常に効率的です。AlbumsRecordTimestampIndex インデックスが選択されます。「happy」という単語を含むアルバムが多数ある場合でも、クエリは少数の行のみをスキャンします。

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, 'happy')
    ORDER BY RecordTimestamp DESC
    LIMIT 10
    
  • ReleaseTimestamp の降順で並べ替えをリクエストする同じクエリは、AlbumsReleaseTimestampIndex インデックスを使用し、同等に効率的です。

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, 'happy')
    ORDER BY ReleaseTimestamp DESC
    LIMIT 10
    
  • 同時に、ListenTimestamp による並べ替え順序をリクエストするクエリは、上位 k 件クエリを効率的に実行しません。一致するすべてのアルバムをフェッチし、ListenTimestamp, で並べ替えて、上位 10 個を返す必要があります。このようなクエリは、「happy」という語を含むドキュメントが大量にある場合、より多くのリソースを使用します。

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, 'happy')
    ORDER BY ListenTimestamp DESC
    LIMIT 10
    
  • 同様に、結果を RecordTimestamp 列で昇順に並べ替えるようにリクエストすると、クエリは効率的に実行されません。LIMIT が設定されていても、「happy」という単語を含むすべての行がスキャンされます。

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, 'happy')
    ORDER BY RecordTimestamp ASC
    LIMIT 10
    

次のステップ