數值搜尋索引

除了為文字建立索引外,搜尋索引也能有效為數字建立索引。主要用於在全文搜尋查詢中,加入數值欄位的條件。本頁面說明如何為等式和不等式查詢建立數字索引,以及為數字陣列建立索引。

將數字權杖化

數字權杖化工具用於產生一組權杖,以加速數值比較搜尋。

使用 TOKENIZE_NUMBER 函式建立數值索引。TOKENIZE_NUMBER 支援 INT64、FLOAT32、FLOAT64 或 ARRAY 這些類型。

如果是 PostgreSQL,請使用 spanner.tokenize_number 函式建立數值索引。spanner.tokenize_number 僅支援 bigint 類型。

等式和不等式查詢的索引編號

Spanner 支援等式和不等式的索引編號。等式搜尋會比對數字。範圍和不等式搜尋會比對特定範圍內的數字。您可以在 TOKENIZE_NUMBER comparison_type 參數中設定這個值:

  • 平等:comparison_type=>"equality"
  • 不等式和等式:comparison_type=>"all"

在這兩種情況下,原始數字 (整數或浮點數) 都會經過權杖化程序,概念上類似於全文權杖化。它會產生一組權杖,查詢可使用這些權杖找出符合數字條件的文件。

等式索引只會產生一個代表數字的符記。如果查詢在 WHERE 子句中只有 field = @p 形式的條件,建議使用這個模式。

不相等和相等索引可加快查詢 WHERE 子句中更多條件的執行速度。除了等式條件外,還包括 field < @p、field <= @p、field > @p、field >= @p、field BETWEEN @p1 and @p2 和 field <> @p。為實作這類索引,Spanner 會在基礎搜尋索引中產生權杖。Spanner 可為每個已建立索引的數字產生多個權杖,具體取決於調整參數。權杖數量取決於為 TOKENIZE_NUMBER 設定的參數,例如 algorithm、min、max 和 granularity。因此,請務必仔細評估調整參數,確保磁碟儲存空間和查詢時間之間取得適當平衡。

針對 INT64 等整數類型的範圍查詢,指定 algorithm => "prefixtree" 可大幅提升效能,效果優於預設的 logtree 演算法。這個演算法會根據數字前置字元產生權杖,更有效率地刪除範圍條件 (例如 <= 和 >=) 的搜尋空間。如果查詢的 WHERE 子句包含範圍述詞,prefixtree 演算法會為小數字產生比 logtree 更少的索引權杖,進而提升效能並降低儲存成本。

陣列權杖化

除了純量值之外,TOKENIZE_NUMBER 也支援數字陣列的權杖化 (本節範例適用於 GoogleSQL 方言資料庫;PostgreSQL 不支援使用搜尋索引加速數字陣列)。

如果 TOKENIZE_NUMBER 與 ARRAY 欄搭配使用,則必須指定 comparison_type=>"equality"。不支援使用數字陣列進行範圍查詢。

  CREATE TABLE Albums (
    AlbumId STRING(MAX) NOT NULL,
    Ratings ARRAY<INT64>,
    Ratings_Tokens TOKENLIST
      AS (TOKENIZE_NUMBER(Ratings, comparison_type=>"equality")) HIDDEN
  ) PRIMARY KEY(AlbumId);

  CREATE SEARCH INDEX AlbumsIndex ON Albums(Ratings_Tokens);
  ```

The following query finds all albums that have a rating of 1 or 2:

 ```sql
  SELECT AlbumId
  FROM Albums
  WHERE ARRAY_INCLUDES_ANY(Ratings, [1, 2])
  ```

The following query finds all albums that were rated as 1 and as 5:

```sql
SELECT AlbumId
FROM Albums
WHERE ARRAY_INCLUDES_ALL(Ratings, [1, 5])
```

### Options for indexing high-precision numbers not supported by `TOKENIZE_NUMBER`

If you need to perform search queries on numeric types not directly supported by
`TOKENIZE_NUMBER` (such as `NUMERIC` or `BIGNUMERIC`),
consider these options:

*   **Schema Modification:** Change the column type to `INT64` for the subset of
    data that fits within the `INT64` range. Handle values exceeding the `INT64`
    range separately, potentially in a different table or using application
    logic.

*   **Conceptual Mapping to Supported Types:** Explore creating generated
    columns to map the `NUMERIC` values to an `INT64` range. This would allow
    `TOKENIZE_NUMBER` to be used on the generated column. Be sure to validate
    the query results against the original `NUMERIC` column in case your mapping
    does not perfectly preserve precision. The specifics of the mapping function
    needed for this approach are highly dependent on your specific data.

## What's next

*   Learn about [tokenization and Spanner
    tokenizers](/spanner/docs/full-text-search/tokenization).
*   Learn about [search indexes](/spanner/docs/full-text-search/search-indexes).
*   Learn about [index
    partitioning](/spanner/docs/full-text-search/partition-search-index).