多くのアプリケーションは、データベースにクエリを実行して、アプリケーションの 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
次のステップ
- 全文検索クエリについて学習する。
- 検索結果をランク付けする方法を確認する。
- 検索結果をページ分けする方法を学習する。
- 全文クエリと非テキストクエリを組み合わせる方法を学習する。
- 複数の列を検索する方法について学ぶ。