管理搜尋索引

您可以在 BigQuery 中建立搜尋索引,使用 SEARCH 函式有效率地搜尋字串資料中的文字。建立這些輔助資料結構,可大幅提升支援函式和運算子的整體查詢效能。

建立搜尋索引

如要建立搜尋索引,請使用 CREATE SEARCH INDEX DDL 陳述式。如要指定要建立索引的基本資料類型,請參閱「建立搜尋索引並指定資料欄和資料類型」。如未指定任何資料類型,BigQuery 預設會為下列類型中含有 STRING 資料的資料欄建立索引:

  • STRING
  • ARRAY<STRING>
  • STRUCT 包含至少一個 STRING 或 ARRAY<STRING> 類型的巢狀欄位
  • JSON

建立搜尋索引時,您可以指定要使用的文字分析器類型。文字分析器可控管資料如何權杖化,以便建立索引及搜尋。預設值為 LOG_ANALYZER。這個分析器適用於機器產生的記錄,並針對可觀測的資料中常見的權杖 (例如 IP 位址或電子郵件) 制定特殊規則。如果您有預先處理過的資料,且想要完全比對,請使用 NO_OP_ANALYZER。PATTERN_ANALYZER 會使用規則運算式從文字中擷取權杖。

使用預設文字分析器建立搜尋索引

在以下範例中,系統會在 simple_table 的 a 和 c 資料欄建立搜尋索引,並預設使用 LOG_ANALYZER 文字分析器:

CREATE TABLE dataset.simple_table(a STRING, b INT64, c JSON);

CREATE SEARCH INDEX my_index
ON dataset.simple_table(a, c);

使用 NO_OP_ANALYZER 分析器,為所有資料欄建立搜尋索引

在 ALL COLUMNS 建立搜尋索引時,系統會為資料表中的所有 STRING 或 JSON 資料建立索引。如果資料表不含這類資料 (例如所有資料欄都包含整數),則無法建立索引。指定要建立索引的 STRUCT 欄時,系統會為所有巢狀子欄位建立索引。

在以下範例中,系統會在 a、c.e 和 c.f.g 上建立搜尋索引,並使用 NO_OP_ANALYZER 文字分析器:

CREATE TABLE dataset.my_table(
  a STRING,
  b INT64,
  c STRUCT <d INT64,
            e ARRAY<STRING>,
            f STRUCT<g STRING, h INT64>>) AS
SELECT 'hello' AS a, 10 AS b, (20, ['x', 'y'], ('z', 30)) AS c;

CREATE SEARCH INDEX my_index
ON dataset.my_table(ALL COLUMNS)
OPTIONS (analyzer = 'NO_OP_ANALYZER');

由於搜尋索引是在 ALL COLUMNS 上建立,因此新增至資料表的任何資料欄,只要含有 STRING 資料,就會自動建立索引。

建立搜尋索引,並指定資料欄和資料類型

建立搜尋索引時,您可以指定要使用的資料類型。資料類型會控制 JSON 和 STRUCT 資料欄的資料欄和子欄位類型,以便建立索引。索引的預設資料類型為 STRING。如要建立包含更多資料類型 (例如數值類型) 的搜尋索引,請使用 CREATE SEARCH INDEX 陳述式,並加入 data_types 選項。

在以下範例中,系統會為名為 simple_table 的資料表,建立 a、b、c 和 d 欄的搜尋索引。支援的資料欄資料類型為 STRING、INT64 和 TIMESTAMP。

CREATE TABLE dataset.simple_table(a STRING, b INT64, c JSON, d TIMESTAMP);

CREATE SEARCH INDEX my_index
ON dataset.simple_table(a, b, c, d)
OPTIONS ( data_types = ['STRING', 'INT64', 'TIMESTAMP']);

為所有資料欄建立搜尋索引,並指定資料類型

在 ALL COLUMNS 上建立搜尋索引並指定 data_types 選項時,系統會為符合指定資料類型的任何資料欄建立索引。如果是 JSON 和 STRUCT 資料欄,系統會為符合其中一種指定資料類型的巢狀子欄位建立索引。

在以下範例中,系統會在 ALL COLUMNS 上建立搜尋索引,並指定資料類型。為名為 my_table 的資料表建立索引的資料欄:a、b、c、d.e、d.f、d.g.h、d.g.i

CREATE TABLE dataset.my_table(
  a STRING,
  b INT64,
  c TIMESTAMP,
  d STRUCT <e INT64,
            f ARRAY<STRING>,
            g STRUCT<h STRING, i INT64>>)
AS (
  SELECT
    'hello' AS a,
    10 AS b,
    TIMESTAMP('2008-12-25 15:30:00 UTC') AS c,
    (20, ['x', 'y'], ('z', 30)) AS d;
)

CREATE SEARCH INDEX my_index
ON dataset.my_table(ALL COLUMNS)
OPTIONS ( data_types = ['STRING', 'INT64', 'TIMESTAMP']);

由於搜尋索引是在 ALL COLUMNS 上建立,因此新增至資料表的任何資料欄,只要符合任何指定的資料類型,就會自動建立索引。

以資料欄精細程度建立索引

建立搜尋索引時,您可以指定索引資料欄的資料欄精細程度。資料欄精細程度可讓 BigQuery 在搜尋索引中儲存額外的資料欄資訊,藉此最佳化特定類型的搜尋查詢。如要設定索引資料欄的資料欄精細程度,請在執行 CREATE SEARCH INDEX 陳述式時,使用 index_column_option_list 中的 index_granularity 選項。

在內部,BigQuery 資料表會整理成檔案。建立索引時,BigQuery 會建立從權杖到包含這些權杖的檔案的對應。執行搜尋查詢時,BigQuery 會掃描所有含有權杖的檔案。如果搜尋權杖很少出現在搜尋的資料欄中,但經常出現在其他資料欄中,這種做法可能效率不彰。

舉例來說,假設您有下列包含徵人啟事的資料表:

CREATE TABLE my_dataset.job_postings (job_id INT64, company_name STRING, job_description STRING);

「skills」這個字可能經常出現在 job_description 欄,但很少出現在 company_name 欄。假設您執行下列查詢:

SELECT * FROM my_dataset.job_postings WHERE SEARCH(company_name, 'skills');

如果您在 company_name 和 job_description 資料欄建立搜尋索引,但未指定資料欄精細程度,BigQuery 就會掃描 job_description 或 company_name 資料欄中出現「skills」一詞的所有檔案。如要提高這項查詢的效能,您可以將 company_name 的資料欄精細程度設為 COLUMN:

CREATE SEARCH INDEX my_index
ON my_dataset.job_postings (
  company_name OPTIONS(index_granularity = 'COLUMN'),
  job_description);

現在執行查詢時,BigQuery 只會掃描 company_name 欄中含有「skills」一詞的檔案。

如要查看索引資料表資料欄上設定的選項資訊,請查詢 INFORMATION_SCHEMA.SEARCH_INDEX_COLUMN_OPTIONS 檢視表。

可依資料欄精細程度建立索引的資料欄數量有限。詳情請參閱「配額與限制」。

瞭解索引重新整理

搜尋索引由 BigQuery 全代管,並在資料表變更時自動重新整理。在下列情況下,索引可能會全面重新整理:

  • 分區到期時間已更新。
  • 資料表結構定義變更,導致索引資料欄更新。
  • 由於缺少 BACKGROUND 預留運算單元,無法進行增量重新整理,因此索引已過時。為避免過時,您可以使用自動調度資源功能,並監控工作負載,判斷最佳基準和預留項目大小上限。

如果每列的索引資料欄資料都更新 (例如在回填作業期間),則必須更新整個索引,這相當於完整重新整理。建議您慢慢執行補充作業 (例如逐一分區),盡可能降低潛在負面影響。

如果您對基礎資料表進行任何結構定義變更,導致明確建立索引的資料欄無法建立索引,則索引會永久停用。

如果刪除資料表中唯一建立索引的資料欄,或重新命名資料表本身,系統會自動刪除搜尋索引。

搜尋索引適用於大型資料表。如果資料表小於 10 GB,則建立搜尋索引時不會填入資料。同樣地,如果您從已建立索引的資料表刪除資料,且資料表大小低於 10 GB,系統會暫時停用索引。在這種情況下,搜尋查詢不會使用索引,且 IndexUnusedReason 程式碼為 BASE_TABLE_TOO_SMALL。無論您是否使用自己的預留項目執行索引管理工作,都會發生這種情況。如果索引資料表的大小超過 10 GB,系統會自動填入索引。在搜尋索引填入資料並啟用之前,系統不會收取儲存空間費用。即使部分資料尚未建立索引,使用 SEARCH 函式的查詢一律會傳回正確結果。

更新搜尋索引

如要更新搜尋索引的設定,請使用 ALTER SEARCH INDEX DDL 陳述式。更新索引特別適合大型資料表,因為您可以進行增量變更,而不必捨棄索引並以新設定重新建立。

更新搜尋索引時,BigQuery 會以非同步方式建立修訂後的索引,並盡可能重複使用原始索引。修訂後的索引填入足夠資料後,就會成為基礎資料表的索引。

下表可協助您瞭解不同索引變更的費用:

動作 說明 費用
捨棄資料欄。 立即更新設定。如未指定 REBUILD,則這項作業只會處理中繼資料。 不會使用額外的運算單元。
新增資料欄或資料類型。 處理新資料並重複使用現有索引資料,建立修訂後的索引。 與要建立索引的新資料量成正比。
變更權杖精細程度、合併多項變更,或清理儲存空間。 從頭開始重建索引。這項作業會移除先前捨棄的資料欄或資料類型中的資料。這項清理作業會縮減索引大小,進而提升查詢效能。 與索引資料總大小成正比。

您可以使用 INFORMATION_SCHEMA.SEARCH_INDEXES 檢視畫面中的 last_index_alteration_info 欄位,追蹤修訂後索引的涵蓋範圍。舉例來說,下列查詢會顯示專案 my_project 中資料集 my_dataset 資料表上所有索引的變更狀態。如果索引變更作業已完成,last_index_alteration_info 的值會是 NULL。

SELECT
  table_name,
  index_name,
  last_index_alteration_info.status AS status,
  last_index_alteration_info.new_coverage_percentage AS coverage
FROM my_project.my_dataset.INFORMATION_SCHEMA.SEARCH_INDEXES

傳回的結果看起來類似下列內容:

+------------+------------+-------------+----------+
| table_name | index_name | status      | coverage |
+------------+------------+-------------+----------+
| table1     | index_a    | IN_PROGRESS | 50       |
| table2     | index_b    | null        | null     |
+------------+------------+-------------+----------+

如要取消索引變更,請使用 BQ.CANCEL_INDEX_ALTERATION 系統程序。修改完成後即無法取消。

取得搜尋索引相關資訊

您可以查詢 INFORMATION_SCHEMA,確認搜尋索引是否存在且已就緒。有三個檢視表包含搜尋索引的中繼資料。

INFORMATION_SCHEMA.SEARCH_INDEXES 查看範例

本節包含 INFORMATION_SCHEMA.SEARCH_INDEXES 檢視表的查詢範例。

以下範例顯示專案 my_project 中資料集 my_dataset 資料表的所有有效搜尋索引。包括名稱、用於建立索引的 DDL 陳述式、涵蓋率百分比和文字分析器。如果已建立索引的基礎資料表小於 10 GB,就不會填入索引,在這種情況下,coverage_percentage 為 0。

SELECT table_name, index_name, ddl, coverage_percentage, analyzer
FROM my_project.my_dataset.INFORMATION_SCHEMA.SEARCH_INDEXES
WHERE index_status = 'ACTIVE';

結果應如下所示:

+-------------+-------------+--------------------------------------------------------------------------------------+---------------------+----------------+
| table_name  | index_name  | ddl                                                                                  | coverage_percentage | analyzer       |
+-------------+-------------+--------------------------------------------------------------------------------------+---------------------+----------------+
| small_table | names_index | CREATE SEARCH INDEX `names_index` ON `my_project.my_dataset.small_table`(names)      | 0                   | NO_OP_ANALYZER |
| large_table | logs_index  | CREATE SEARCH INDEX `logs_index` ON `my_project.my_dataset.large_table`(ALL COLUMNS) | 100                 | LOG_ANALYZER   |
+-------------+-------------+--------------------------------------------------------------------------------------+---------------------+----------------+

INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS 查看範例

本節包含 INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS 檢視表的查詢範例。

以下範例會為 my_table 的所有資料欄建立搜尋索引。

CREATE TABLE dataset.my_table(
  a STRING,
  b INT64,
  c STRUCT <d INT64,
            e ARRAY<STRING>,
            f STRUCT<g STRING, h INT64>>) AS
SELECT 'hello' AS a, 10 AS b, (20, ['x', 'y'], ('z', 30)) AS c;

CREATE SEARCH INDEX my_index
ON dataset.my_table(ALL COLUMNS);

下列查詢會擷取已建立索引的欄位資訊。index_field_path 表示資料欄的哪個欄位已建立索引。這與 index_column_name 的差異僅在於 STRUCT,其中會提供索引欄位的完整路徑。在這個範例中,c 欄包含 ARRAY<STRING> 欄位 e 和另一個名為 f 的 STRUCT,其中包含 STRING 欄位 g,每個欄位都已建立索引。

SELECT table_name, index_name, index_column_name, index_field_path
FROM my_project.dataset.INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS

結果大致如下:

+------------+------------+-------------------+------------------+
| table_name | index_name | index_column_name | index_field_path |
+------------+------------+-------------------+------------------+
| my_table   | my_index   | a                 | a                |
| my_table   | my_index   | c                 | c.e              |
| my_table   | my_index   | c                 | c.f.g            |
+------------+------------+-------------------+------------------+

下列查詢會將 INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS 檢視表與 INFORMATION_SCHEMA.SEARCH_INDEXES 和 INFORMATION_SCHEMA.COLUMNS 檢視表彙整,納入搜尋索引狀態和各資料欄的資料類型:

SELECT
  index_columns_view.index_catalog AS project_name,
  index_columns_view.index_SCHEMA AS dataset_name,
  indexes_view.TABLE_NAME AS table_name,
  indexes_view.INDEX_NAME AS index_name,
  indexes_view.INDEX_STATUS AS status,
  index_columns_view.INDEX_COLUMN_NAME AS column_name,
  index_columns_view.INDEX_FIELD_PATH AS field_path,
  columns_view.DATA_TYPE AS data_type
FROM
  mydataset.INFORMATION_SCHEMA.SEARCH_INDEXES indexes_view
INNER JOIN
  mydataset.INFORMATION_SCHEMA.SEARCH_INDEX_COLUMNS index_columns_view
  ON
    indexes_view.TABLE_NAME = index_columns_view.TABLE_NAME
    AND indexes_view.INDEX_NAME = index_columns_view.INDEX_NAME
LEFT OUTER JOIN
  mydataset.INFORMATION_SCHEMA.COLUMNS columns_view
  ON
    indexes_view.INDEX_CATALOG = columns_view.TABLE_CATALOG
    AND indexes_view.INDEX_SCHEMA = columns_view.TABLE_SCHEMA
    AND index_columns_view.TABLE_NAME = columns_view.TABLE_NAME
    AND index_columns_view.INDEX_COLUMN_NAME = columns_view.COLUMN_NAME
ORDER BY
  project_name,
  dataset_name,
  table_name,
  column_name;

結果大致如下:

+------------+------------+----------+------------+--------+-------------+------------+---------------------------------------------------------------+
| project    | dataset    | table    | index_name | status | column_name | field_path | data_type                                                     |
+------------+------------+----------+------------+--------+-------------+------------+---------------------------------------------------------------+
| my_project | my_dataset | my_table | my_index   | ACTIVE | a           | a          | STRING                                                        |
| my_project | my_dataset | my_table | my_index   | ACTIVE | c           | c.e        | STRUCT<d INT64, e ARRAY<STRING>, f STRUCT<g STRING, h INT64>> |
| my_project | my_dataset | my_table | my_index   | ACTIVE | c           | c.f.g      | STRUCT<d INT64, e ARRAY<STRING>, f STRUCT<g STRING, h INT64>> |
+------------+------------+----------+------------+--------+-------------+------------+---------------------------------------------------------------+

INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION 查看範例

本節包含 INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION 檢視表的查詢範例。

查看特定區域的用量是否超過限制

以下範例說明組織在美國多區域使用共用運算單元,且已建立索引的基礎資料表總大小超過 100 TB:

WITH
 indexed_base_table_size AS (
 SELECT
   SUM(base_table.total_logical_bytes) AS total_logical_bytes
 FROM
   `region-us`.INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION AS search_index
 JOIN
   `region-us`.INFORMATION_SCHEMA.TABLE_STORAGE_BY_ORGANIZATION AS base_table
 ON
   (search_index.table_name = base_table.table_name
     AND search_index.project_id = base_table.project_id
     AND search_index.index_schema = base_table.table_schema)
 WHERE
   TRUE
   -- Excludes search indexes that are permanently disabled.
   AND search_index.index_status != 'PERMANENTLY DISABLED'
   -- Excludes BASE_TABLE_TOO_SMALL search indexes whose base table size is
   -- less than 10 GB. These tables don't count toward the limit.
   AND search_index.index_status_details.throttle_status != 'BASE_TABLE_TOO_SMALL'
   -- Excludes search indexes whose project has BACKGROUND reservation purchased
   -- for search indexes.
   AND search_index.use_background_reservation = false
 -- Outputs the total indexed base table size if it exceeds 100 TB,
 -- otherwise, doesn't return any output.
)
SELECT * FROM indexed_base_table_size
WHERE total_logical_bytes >= 109951162777600 -- 100 TB

結果大致如下:

+---------------------+
| total_logical_bytes |
+---------------------+
|     109951162777601 |
+---------------------+

依區域中的專案,找出已建立索引的基礎資料表總大小

以下範例列出美國多區域中各項專案的細目,以及已建立索引的基礎資料表總大小:

SELECT
 search_index.project_id,
 search_index.use_background_reservation,
 SUM(base_table.total_logical_bytes) AS total_logical_bytes
FROM
 `region-us`.INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION AS search_index
JOIN
 `region-us`.INFORMATION_SCHEMA.TABLE_STORAGE_BY_ORGANIZATION AS base_table
ON
 (search_index.table_name = base_table.table_name
   AND search_index.project_id = base_table.project_id
   AND search_index.index_schema = base_table.table_schema)
WHERE
 TRUE
  -- Excludes search indexes that are permanently disabled.
  AND search_index.index_status != 'PERMANENTLY DISABLED'
  -- Excludes BASE_TABLE_TOO_SMALL search indexes whose base table size is
  -- less than 10 GB. These tables don't count toward limit.
 AND search_index.index_status_details.throttle_status != 'BASE_TABLE_TOO_SMALL'
GROUP BY search_index.project_id, search_index.use_background_reservation

結果大致如下:

+---------------------+----------------------------+---------------------+
|     project_id      | use_background_reservation | total_logical_bytes |
+---------------------+----------------------------+---------------------+
| projecta            |     true                   |     971329178274633 |
+---------------------+----------------------------+---------------------+
| projectb            |     false                  |     834638211024843 |
+---------------------+----------------------------+---------------------+
| projectc            |     false                  |     562910385625126 |
+---------------------+----------------------------+---------------------+

找出受限的搜尋索引

下列範例會傳回組織和區域內,所有受到節流限制的搜尋索引:

SELECT project_id, index_schema, table_name, index_name
FROM
 `region-us`.INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION
WHERE
 -- Excludes search indexes that are permanently disabled.
 index_status != 'PERMANENTLY DISABLED'
 AND index_status_details.throttle_status IN ('ORGANIZATION_LIMIT_EXCEEDED', 'BASE_TABLE_TOO_LARGE')

結果大致如下:

+--------------------+--------------------+---------------+----------------+
|     project_id     |    index_schema    |  table_name   |   index_name   |
+--------------------+--------------------+---------------+----------------+
|     projecta       |     dataset_us     |   table1      |    index1      |
|     projectb       |     dataset_us     |   table1      |    index1      |
+--------------------+--------------------+---------------+----------------+

索引管理選項

如要建立索引並由 BigQuery 維護,有兩種方法:

使用共用運算單元

如果未將專案設為使用專屬預留項目建立索引,系統會在免費的共用運算單元集區中管理索引,但須遵守下列限制。

如果您在資料表中新增資料,導致索引資料表的總大小超過組織限制,BigQuery 會暫停該資料表的索引管理。發生這種情況時,INFORMATION_SCHEMA.SEARCH_INDEXES 檢視畫面中的 index_status 欄位會顯示 PENDING DISABLEMENT,且索引會排入刪除佇列。在索引待停用期間,系統仍會將其用於查詢,並向您收取索引儲存空間費用。刪除索引後,index_status 欄位會將索引顯示為 TEMPORARILY DISABLED。在這個狀態下,查詢不會使用索引,您也不必支付索引儲存費用。在本例中,IndexUnusedReason 代碼為 BASE_TABLE_TOO_LARGE。

如果您從資料表中刪除資料,且已建立索引的資料表總大小低於每個組織的限制,系統就會恢復索引管理。INFORMATION_SCHEMA.SEARCH_INDEXES 檢視表中的 index_status 欄位為 ACTIVE,查詢可以使用索引,且您需要支付索引儲存空間費用。

您可以使用 INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION 檢視畫面,瞭解特定區域中每個組織的目前用量限制,並依專案和資料表細分。

BigQuery 不保證共用集區的可用容量,或您看到的索引處理量。如果是正式環境應用程式,建議您使用專屬運算單元處理索引。

使用自己的預留項目

您可以選擇指定自己的預留項目來為資料表建立索引,而不使用預設的共用運算單元集區。使用自己的預留項目,可確保索引管理工作 (例如建立、重新整理和背景最佳化) 的效能可預測且一致。

  • 在預留項目中執行索引工作時,資料表大小沒有限制。
  • 使用自己的預留項目,可讓您靈活管理索引。如要建立非常大的索引,或對已建立索引的資料表進行重大更新,可以暫時在指派作業中新增更多運算單元。

如要使用指定預留項目為專案中的資料表建立索引,請在資料表所在區域建立預留項目。接著,將專案指派給 job_type 設為 BACKGROUND 的預留項目,以便在背景最佳化工作中分享資源:

SQL

使用 CREATE ASSIGNMENT DDL 陳述式。

  1. 前往 Cloud de Confiance 控制台的「BigQuery」頁面。

    前往「BigQuery」

  2. 在查詢編輯器中輸入下列陳述式:

    CREATE ASSIGNMENT
      `ADMIN_PROJECT_ID.region-LOCATION.RESERVATION_NAME.ASSIGNMENT_ID`
    OPTIONS (
      assignee = 'projects/PROJECT_ID',
      job_type = 'BACKGROUND');

    替換下列內容:

    • ADMIN_PROJECT_ID:擁有預留資源的管理專案 專案 ID
    • LOCATION:預留項目的位置
    • RESERVATION_NAME:預留項目名稱
    • ASSIGNMENT_ID:作業 ID

      ID 在專案和位置中不得重複,開頭和結尾須為小寫英文字母或數字,且只能使用小寫英文字母、數字和破折號。

    • PROJECT_ID:專案 ID,專案中包含要建立索引的資料表。這項專案已指派給預留項目。

  3. 按一下「 執行」。

如要進一步瞭解如何執行查詢,請參閱「執行互動式查詢」。

bq

使用 bq mk 指令:

bq mk \
    --project_id=ADMIN_PROJECT_ID \
    --location=LOCATION \
    --reservation_assignment \
    --reservation_id=RESERVATION_NAME \
    --assignee_id=PROJECT_ID \
    --job_type=BACKGROUND \
    --assignee_type=PROJECT

更改下列內容:

  • ADMIN_PROJECT_ID:擁有預留資源的管理專案 ID
  • LOCATION:預留項目的位置
  • RESERVATION_NAME:預留項目名稱
  • PROJECT_ID:要指派給這項預留項目的專案 ID

查看索引工作

每當在單一資料表建立或更新索引時,系統就會建立新的索引工作。如要查看工作相關資訊,請查詢 INFORMATION_SCHEMA.JOBS* 檢視表。您可以在查詢的 WHERE 子句中設定 job_type IS NULL AND SEARCH(job_id, '`search_index`'),篩選索引工作。下列範例會列出專案 my_project 中最近的五項索引工作:

SELECT *
FROM
 region-us.INFORMATION_SCHEMA.JOBS
WHERE
  project_id  = 'my_project'
  AND job_type IS NULL
  AND SEARCH(job_id, '`search_index`')
ORDER BY
 creation_time DESC
LIMIT 5;

選擇預留項目大小

如要為預留項目選擇合適的運算單元數量,請考量索引管理工作的執行時間、使用的運算單元數量,以及用量隨時間的變化。BigQuery 會在下列情況觸發索引管理工作:

  • 在資料表建立索引。
  • 在已建立索引的資料表中修改資料。
  • 資料表的結構定義有所變更,影響到哪些資料欄會建立索引。
  • 系統會定期最佳化或更新索引資料和中繼資料。

資料表索引管理工作所需的運算單元數量取決於下列因素:

  • 資料表大小
  • 資料擷取至資料表的速率
  • 資料表套用 DML 陳述式的頻率
  • 建構及維護索引時可接受的延遲時間
  • 索引的複雜度,通常取決於資料屬性,例如重複字詞的數量
初步估算

您可以參考下列預估值,大致估算預留項目所需的運算單元數量。由於索引工作負載的變動性極高,建議您在開始建立資料索引後,重新評估需求。

  • 現有資料:如果預留 1,000 個運算單元,BigQuery 現有資料表的平均索引建立速率最高可達每秒 4 GiB,約為每天 336 TiB。
  • 新擷取的資料:資料表和索引會經過多輪轉換最佳化,因此為新擷取的資料建立索引時,通常會耗用較多資源。平均而言,為新擷取的資料建立索引,耗用的資源是為相同資料進行初始回填索引的三倍。
  • 不常修改的資料:如果索引資料表幾乎或完全沒有資料修改,則持續維護索引所需的資源會大幅減少。建議一開始保留 1/5 的運算單元,用於對相同資料進行初始補充索引,且不得少於 250 個運算單元。
  • 索引進度與預留項目大小大致呈線性關係。不過,我們不建議使用少於 250 個運算單元的預留項目進行索引,因為這可能會導致效率不彰,進而減緩索引進度。
  • 這些預估值可能會隨著功能、最佳化和實際用量而變動。
  • 如果貴組織的資料表總大小超過區域的索引限制,請務必保留非零的預留項目,用於建立索引。否則,索引可能會改用預設級別,導致所有索引意外刪除。
監控使用情形和進度

如要評估需要多少運算單元,才能有效率地執行索引管理工作,最好的方法是監控運算單元使用率,並據此調整預留項目大小。下列查詢會產生索引管理工作的每日運算單元用量。區域 us-west1 只會納入過去 30 天的資料:

SELECT
  TIMESTAMP_TRUNC(job.creation_time, DAY) AS usage_date,
  -- Aggregate total_slots_ms used for index-management jobs in a day and divide
  -- by the number of milliseconds in a day. This value is most accurate for
  -- days with consistent slot usage.
  SAFE_DIVIDE(SUM(job.total_slot_ms), (1000 * 60 * 60 * 24)) AS average_daily_slot_usage
FROM
  `region-us-west1`.INFORMATION_SCHEMA.JOBS job
WHERE
  project_id = 'my_project'
  AND job_type IS NULL
  AND SEARCH(job_id, '`search_index`')
GROUP BY
  usage_date
ORDER BY
  usage_date DESC
limit 30;

如果沒有足夠的運算單元來執行索引管理工作,索引可能會與資料表不同步,且索引工作可能會失敗。在這種情況下,BigQuery 會從頭重建索引。為避免索引不同步,請確保有足夠的運算單元,可支援資料擷取和最佳化作業的索引更新。如要進一步瞭解如何監控運算單元用量,請參閱「管理員資源圖表」。

最佳做法

  • 搜尋索引適用於大型資料表。搜尋索引帶來的效能提升幅度會隨著資料表大小而增加。
  • 請勿為僅包含極少數不重複值的資料欄建立索引。
  • 請勿為不打算與 SEARCH 函式或任何其他支援的函式和運算子搭配使用的資料欄建立索引。
  • 在 ALL COLUMNS 建立搜尋索引時,請務必謹慎。每當您新增包含 STRING 或 JSON 資料的資料欄,系統就會建立索引。
  • 在正式環境應用程式中,您應使用自己的預留項目管理索引。如果選擇使用預設共用運算單元集區執行索引管理工作,則適用各組織的大小限制。

刪除搜尋索引

如果不再需要搜尋索引,或想變更資料表中建立索引的資料欄,可以刪除資料表目前的索引。使用 DROP SEARCH INDEX DDL 陳述式。

如果刪除已建立索引的資料表,系統會自動刪除其索引。

範例:

DROP SEARCH INDEX my_index ON dataset.simple_table;

後續步驟