Spanner 支援未分割和已分割的搜尋索引。本頁說明如何在 Spanner 中建立分割搜尋索引。
如果在索引定義中省略 PARTITION BY
子句,系統就會建立未分割的索引。在未分割的索引中,查詢需要從所有索引分割項目讀取。這會限制全文搜尋查詢的潛在可擴充性。
另一方面,分區索引會將索引細分為較小的單位,每個獨特分區各有一個。查詢只能在 WHERE
子句中指定的等式條件中,一次搜尋單一區隔。針對已分區索引的查詢通常比針對未分區索引的查詢更有效率,因為 Spanner 只需要讀取單一分區的資料。搜尋索引的分割方式類似次要索引的索引鍵前置字串。
舉例來說,假設資料庫中有 1,000,000 個 SingerIds
,以及以下兩個索引:
GoogleSQL
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
SingerId STRING(MAX) NOT NULL,
ReleaseTimestamp INT64 NOT NULL,
AlbumTitle STRING(MAX),
AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN,
SingerId_Tokens TOKENLIST AS (TOKEN(SingerId)) HIDDEN
) PRIMARY KEY(SingerId, AlbumId);
CREATE SEARCH INDEX AlbumsUnpartitionedIndex
ON Albums(AlbumTitle_Tokens, SingerId_Tokens);
CREATE SEARCH INDEX AlbumsIndexBySingerId
ON Albums(AlbumTitle_Tokens)
PARTITION BY SingerId;
PostgreSQL
CREATE TABLE albums (
albumid character varying NOT NULL,
singerid character varying NOT NULL,
releasetimestamp bigint NOT NULL,
albumtitle character varying,
albumtitle_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.tokenize_fulltext(albumtitle)) VIRTUAL HIDDEN,
singerid_tokens spanner.tokenlist GENERATED ALWAYS AS (spanner.token(singerid)) VIRTUAL HIDDEN,
PRIMARY KEY(singerid, albumid));
CREATE SEARCH INDEX albumsunpartitionedindex
ON albums(albumtitle_tokens, singerid_tokens);
CREATE SEARCH INDEX albumsindexbysingerid
ON albums(albumtitle_tokens)
PARTITION BY singerid;
以下查詢會選取 AlbumsIndexBySingerId
索引,因為它只會搜尋單一歌手的資料。這類查詢通常會使用較少的資源。
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SingerId = "singer1"
AND SEARCH(AlbumTitle_Tokens, 'happy')
PostgreSQL
SELECT albumid
FROM albums
WHERE singerid = 'singer1'
AND spanner.search(albumtitle_tokens, 'happy')
您也可以強制使用 AlbumsUnpartitionedIndex
來傳回相同結果的查詢。不過,這會使用更多資源,因為查詢需要存取所有索引分割項目,並篩選所有專輯的所有歌手,以便找出「happy」符記,而非只篩選與歌手 singer1
對應的分割項目。
不過,應用程式有時需要搜尋所有專輯,而非特定歌手的專輯。在下列情況下,您必須使用未分割的索引:
GoogleSQL
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'piano concerto 1')
PostgreSQL
SELECT albumid
FROM albums
WHERE spanner.search(albumtitle_tokens, 'piano concerto 1')
一般建議使用最精細的分區細目,以便實用且適合查詢。舉例來說,如果應用程式會查詢電子郵件信箱,且每項查詢都限制在特定信箱中,請根據信箱 ID 劃分搜尋索引。不過,如果查詢需要搜尋所有信箱,則不分割索引會更適合。
某些應用程式可能需要多種區隔策略,以滿足特定搜尋需求。舉例來說,商品目錄管理系統可能需要支援依產品類型或製造商篩選的查詢。此外,某些應用程式可能需要多個預先排序,例如依據建立或修改時間排序。在這些情況下,建議您建立多個搜尋索引,並針對各個查詢進行最佳化。Spanner 查詢最佳化器會自動為每個查詢選取索引。
後續步驟
- 瞭解權杖化和 Spanner 分詞器。
- 瞭解搜尋索引。
- 瞭解數字索引。