管理搜尋索引
您可以在 BigQuery 中建立搜尋索引,使用 SEARCH 函式有效率地搜尋字串資料中的文字。建立這些輔助資料結構,可大幅提升支援函式和運算子的整體查詢效能。
建立搜尋索引
如要建立搜尋索引,請使用 CREATE SEARCH INDEX DDL 陳述式。如要指定要建立索引的基本資料類型,請參閱「建立搜尋索引並指定資料欄和資料類型」。如未指定任何資料類型,BigQuery 預設會為下列類型中含有 STRING 資料的資料欄建立索引:
STRINGARRAY<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_INDEX_COLUMNS檢視表會顯示資料集中各資料表的哪些資料欄已建立索引。INFORMATION_SCHEMA.SEARCH_INDEXES_BY_ORGANIZATION檢視畫面包含與目前專案相關聯的整個組織搜尋索引資訊。
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
前往 Cloud de Confiance 控制台的「BigQuery」頁面。
在查詢編輯器中輸入下列陳述式:
CREATE ASSIGNMENT `ADMIN_PROJECT_ID.region-LOCATION.RESERVATION_NAME.ASSIGNMENT_ID` OPTIONS ( assignee = 'projects/PROJECT_ID', job_type = 'BACKGROUND');
替換下列內容:
按一下「 執行」。
如要進一步瞭解如何執行查詢,請參閱「執行互動式查詢」。
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
更改下列內容:
查看索引工作
每當在單一資料表建立或更新索引時,系統就會建立新的索引工作。如要查看工作相關資訊,請查詢 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;
後續步驟
- 如需搜尋索引用途、定價、必要權限和限制的總覽,請參閱「BigQuery 搜尋功能簡介」。
- 如要瞭解如何有效率地搜尋已建立索引的資料欄,請參閱「使用索引搜尋」。