許多應用程式會查詢資料庫,以便在應用程式中填入單一網頁。在這種應用程式中,應用程式不需要所有相符項目,只需要根據索引排序順序取得前 k 個相符項目。搜尋索引可非常有效率地實作這類搜尋。本頁面說明如何建立及搜尋含有前 k 項相符項目的索引。
為前 k 個相符項目建立搜尋索引
如要設定搜尋索引以進行前 k 項比對,請使用 ORDER BY
依特定欄位排序搜尋索引。查詢必須包含 ORDER BY
子句,才能與搜尋索引排序順序 (包括遞增或遞減方向) 完全相符,並且包含 LIMIT
子句,要求查詢在找到 k 個相符資料列後停止。
您也可以使用這些子句實作分頁功能。詳情請參閱「分頁顯示搜尋查詢」。
在某些用途中,您可能需要依不同欄位排序,維護多個搜尋索引。就像分割一樣,您必須在儲存空間和寫入成本與查詢延遲之間取得平衡。
舉例來說,請考慮使用下列結構定義的資料表:
GoogleSQL
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)
STORING (ListenTimestamp)
ORDER BY RecordTimestamp DESC
CREATE SEARCH INDEX AlbumsReleaseTimestampIndex
ON Albums(AlbumTitle_Tokens)
STORING (ListenTimestamp)
ORDER BY ReleaseTimestamp DESC
PostgreSQL
CREATE TABLE albums (
albumid character varying NOT NULL,
recordtimestamp bigint NOT NULL,
releasetimestamp bigint NOT NULL,
listentimestamp bigint NOT NULL,
albumtitle character varying,
albumtitle_tokens spanner.tokenlist
GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));
CREATE SEARCH INDEX albumsrecordtimestampindex
ON Albums(albumtitle_tokens, singerid_tokens)
INCLUDE (listentimestamp)
ORDER BY recordtimestamp DESC
CREATE SEARCH INDEX albumsreleasetimestampindex
ON Albums(albumtitle_tokens)
INCLUDE (listentimestamp)
ORDER BY releasetimestamp DESC
查詢搜尋索引,以取得前 k 項相符項目
如先前所述,查詢必須包含 ORDER BY
子句,才能與搜尋索引排序順序 (包括遞增或遞減方向) 完全相符,並且包含 LIMIT
子句,要求查詢在找到 k 個相符資料列後停止。
下表分析了一些常見查詢的效率。
這項查詢非常有效率。它會選取
AlbumsRecordTimestampIndex
索引。即使有許多專輯含有「happy」一詞,查詢只會掃描少數資料列:GoogleSQL
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, 'happy') ORDER BY RecordTimestamp DESC LIMIT 10
PostgreSQL
SELECT albumid FROM albums WHERE spanner.search(albumtitle_tokens, 'happy') ORDER BY recordtimestamp DESC LIMIT 10
同樣的查詢要求以遞減順序依
ReleaseTimestamp
排序,會使用AlbumsReleaseTimestampIndex
索引,效率也一樣高:GoogleSQL
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, 'happy') ORDER BY ReleaseTimestamp DESC LIMIT 10
PostgreSQL
SELECT albumid FROM albums WHERE spanner.search(albumtitle_tokens, 'happy') ORDER BY releasetimestamp DESC LIMIT 10
要求依
ListenTimestamp
排序的查詢不會以有效率的方式執行前 k 項查詢。必須擷取所有相符的專輯,並依ListenTimestamp,
排序,然後傳回前 10 個。如果有大量文件包含「happy」一詞,這類查詢會使用更多資源。GoogleSQL
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, 'happy') ORDER BY ListenTimestamp DESC LIMIT 10
PostgreSQL
SELECT albumid FROM albums WHERE spanner.search(albumtitle_tokens, 'happy') ORDER BY listentimestamp DESC LIMIT 10
同樣地,如果查詢要求以遞增順序使用
RecordTimestamp
欄排序結果,查詢執行效率就會降低。即使有LIMIT
,它也會掃描所有包含「happy」一詞的資料列。GoogleSQL
SELECT AlbumId FROM Albums WHERE SEARCH(AlbumTitle_Tokens, 'happy') ORDER BY RecordTimestamp ASC LIMIT 10
PostgreSQL
SELECT albumid FROM albums WHERE spanner.search(albumtitle_tokens, 'happy') ORDER BY recordtimestamp ASC LIMIT 10
後續步驟
- 瞭解全文搜尋查詢。
- 瞭解如何排序搜尋結果。
- 瞭解如何分頁顯示搜尋結果。
- 瞭解如何混合全文查詢和非文字查詢。
- 瞭解如何搜尋多個欄。