管理向量索引

本文档介绍了如何创建和管理向量索引,以加快向量搜索速度。

向量索引是一种数据结构,旨在让 VECTOR_SEARCH 函数更高效地执行,尤其是在大型数据集上。使用索引时,VECTOR_SEARCH 会使用近似最近邻 (ANN) 算法来缩短查询延迟时间并降低计算开销。虽然 ANN 会引入一定程度的近似,这意味着召回率可能不是 100%,但对于大多数应用而言,性能提升通常会带来优势。

角色与权限

要创建向量索引,您需要对要在其中创建索引的表拥有 bigquery.tables.createIndex IAM 权限。要删除向量索引,您需要拥有 bigquery.tables.deleteIndex 权限。以下每个预定义的 IAM 角色都包含使用向量索引所需的权限:

  • BigQuery Data Owner (roles/bigquery.dataOwner)
  • BigQuery Data Editor (roles/bigquery.dataEditor)

选择向量索引类型

BigQuery 提供两种向量索引类型,即 IVFTreeAH,每种索引都支持不同的用例。BigQuery 支持通过在 VECTOR_SEARCH 函数中处理多行输入数据来对矢量搜索进行批处理。对于小批量查询,首选 IVF 索引。对于大型批量查询,建议使用使用 Google ScaNN 算法构建的 TreeAH 索引。

IVF 指数

IVF 是倒排文件索引,使用 k-means 算法对向量数据进行聚类,然后根据这些聚类对向量数据进行分区。VECTOR_SEARCH 函数可以使用这些分区来减少为确定结果而需要读取的数据量。

TreeAH 索引

TreeAH 索引类型之所以得名如此,是因为它结合了树状结构,并使用了非对称哈希 (AH),后者是底层 ScaNN 算法的核心量化技术。TreeAH 索引的工作原理如下:

  1. 基表被分成更小、更易于管理的分片。
  2. 使用从 CREATE VECTOR INDEX 语句的 tree_ah_options 参数中的 leaf_node_embedding_count 选项派生的聚类数量来训练聚类模型。
  3. 向量使用产品量化技术进行压缩,这种技术可减少向量占用的内存。然后,压缩后的向量会存储在索引表中,而不是原始向量,从而减小向量索引大小。
  4. 运行 VECTOR_SEARCH 函数时,系统会使用非对称哈希高效地计算每个查询向量的候选列表。该非对称哈希针对近似距离计算进行了硬件优化。然后,使用精确嵌入对这些候选项重新评分和重新排名。

TreeAH 算法针对处理数百个或更多查询向量的批量查询进行了优化。与 IVF 相比,使用产品量化可以显著缩短延迟时间并减少费用,而且有望减少几个数量级。但是,由于开销增加,当您的查询向量较少时,IVF 算法可能更出色。

如果您的用例满足以下条件,我们建议您尝试使用 TreeAH 索引类型:

  • 您的表包含的行数不超过 2 亿。

  • 您经常执行涉及数百个或更多查询向量的大型批量查询。

对于使用 TreeAH 索引类型的小批量查询,VECTOR_SEARCH 可能会回退为使用暴力搜索。在这种情况下,系统会提供 IndexUnusedReason 来说明未使用向量索引的原因。

创建 IVF 向量索引

如需创建 IVF 向量索引,请使用 CREATE VECTOR INDEX 数据定义语言 (DDL) 语句:

  1. 转到 BigQuery 页面。

    转到 BigQuery

  2. 在查询编辑器中,运行以下 SQL 语句:

    如需创建 IVF 向量索引,请执行以下操作:

    CREATE [ OR REPLACE ] VECTOR INDEX [ IF NOT EXISTS ] INDEX_NAME
    ON DATASET_NAME.TABLE_NAME(COLUMN_NAME)
    STORING(STORED_COLUMN_NAME [, ...])
    OPTIONS(index_type = 'IVF',
      distance_type = 'DISTANCE_TYPE',
      ivf_options = '{"num_lists":NUM_LISTS}')

    替换以下内容:

    • INDEX_NAME:您要创建的向量索引的名称。由于索引始终在基表所在的项目和数据集中创建,因此无需在名称中指定这些内容。
    • DATASET_NAME:包含该表的数据集的名称。
    • TABLE_NAME:包含嵌入数据列的表的名称。
    • COLUMN_NAME:包含嵌入数据的列的名称。该列的类型必须是 ARRAY<FLOAT64>。该列不能有任何子字段。数组中的所有元素都必须为非 NULL,且列中的所有值都必须具有相同的数组维度。
    • STORED_COLUMN_NAME:表中要存储在向量索引中的顶级列的名称。列类型不能为 RANGE。如果表具有行级访问权限政策或是列具有政策标记,则不会使用存储列。如需了解如何启用存储列,请参阅存储列和预先过滤
    • DISTANCE_TYPE:指定使用此索引执行向量搜索时要使用的默认距离类型。支持的值为 EUCLIDEANCOSINEDOT_PRODUCT。默认值为 EUCLIDEAN

      索引创建本身始终使用 EUCLIDEAN 距离进行训练,但 VECTOR_SEARCH 函数中使用的距离可能不同。

      如果您为 VECTOR_SEARCH 函数的 distance_type 参数指定值,则系统会使用该值(而非 DISTANCE_TYPE 值)。

    • NUM_LISTSINT64 值,用于指定 IVF 索引将向量数据分块为列表的数量。此值不得超过 5,000。在编制索引期间,系统会将矢量分配给与其最近的簇中心对应的列表。如果您省略此参数,BigQuery 会根据您的数据特征确定默认值。默认值适用于大多数用例。

      NUM_LISTS 用于控制查询调整粒度。值越高,创建的列表就越多,因此您可以将 VECTOR_SEARCH 函数的 fraction_lists_to_search 选项设置为扫描较小百分比的索引。例如,扫描 100 个列表中的 1%,而不是扫描 10 个列表中的 10%。这样可以更精细地控制搜索速度和召回率,但会略微增加索引编制费用。请根据您需要调整查询范围的精确程度来设置此参数值。

以下示例在 my_tableembedding 列上创建向量索引:

CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>);

CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding)
OPTIONS(index_type = 'IVF');

以下示例在 my_tableembedding 列上创建矢量索引,并指定要使用的距离类型和 IVF 选项:

CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>);

CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding)
OPTIONS(index_type = 'IVF', distance_type = 'COSINE',
ivf_options = '{"num_lists": 2500}')

创建 TreeAH 向量索引

如需创建 TreeAH 向量索引,请使用 CREATE VECTOR INDEX 数据定义语言 (DDL) 语句:

  1. 转到 BigQuery 页面。

    转到 BigQuery

  2. 在查询编辑器中,运行以下 SQL 语句:

    CREATE [ OR REPLACE ] VECTOR INDEX [ IF NOT EXISTS ] INDEX_NAME
    ON DATASET_NAME.TABLE_NAME(COLUMN_NAME)
    STORING(STORED_COLUMN_NAME [, ...])
    OPTIONS(index_type = 'TREE_AH',
      distance_type = 'DISTANCE_TYPE',
      tree_ah_options = '{"leaf_node_embedding_count":LEAF_NODE_EMBEDDING_COUNT,
        "normalization_type":"NORMALIZATION_TYPE"}')

    替换以下内容:

    • INDEX_NAME:您要创建的向量索引的名称。由于索引始终在基表所在的项目和数据集中创建,因此无需在名称中指定这些内容。
    • DATASET_NAME:包含该表的数据集的名称。
    • TABLE_NAME:包含嵌入数据列的表的名称。
    • COLUMN_NAME:包含嵌入数据的列的名称。该列的类型必须是 ARRAY<FLOAT64>。该列不能有任何子字段。数组中的所有元素都必须为非 NULL,且列中的所有值都必须具有相同的数组维度。
    • STORED_COLUMN_NAME:表中要存储在向量索引中的顶级列的名称。列类型不能为 RANGE。如果表具有行级访问权限政策或是列具有政策标记,则不会使用存储列。如需了解如何启用存储列,请参阅存储列和预先过滤
    • DISTANCE_TYPE:可选参数,用于指定使用此索引执行向量搜索时要使用的默认距离类型。支持的值为 EUCLIDEANCOSINEDOT_PRODUCT。默认值为 EUCLIDEAN

      索引创建本身始终使用 EUCLIDEAN 距离进行训练,但 VECTOR_SEARCH 函数中使用的距离可能不同。

      如果您为 VECTOR_SEARCH 函数的 distance_type 参数指定值,则系统会使用该值(而非 DISTANCE_TYPE 值)。

    • LEAF_NODE_EMBEDDING_COUNT:一个大于或等于 500 的 INT64 值,指定 TreeAH 算法创建的树的每个叶节点中向量的近似数量。TreeAH 算法将整个数据空间划分为若干个列表,每个列表包含大约 LEAF_NODE_EMBEDDING_COUNT 个数据点。若值越小,则创建的列表就越多,数据点数量越少;若值越大,则创建的列表就越少,数据点数量越多。默认值为 1,000,适用于大多数数据集。

    • NORMALIZATION_TYPE:一个 STRING 值。支持的值为 NONEL2。默认值为 NONE。 标准化会在对基表数据和查询数据执行任何处理之前进行,但不会修改 TABLE_NAME 中的嵌入列 COLUMN_NAME。根据数据集、嵌入模型以及 VECTOR_SEARCH 期间使用的距离类型,对嵌入进行标准化可能会提高召回率。

以下示例在 my_tableembedding 列上创建向量索引,并指定要使用的距离类型和 TreeAH 选项:

CREATE TABLE my_dataset.my_table(id INT64, embedding ARRAY<FLOAT64>);

CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding)
OPTIONS (index_type = 'TREE_AH', distance_type = 'EUCLIDEAN',
tree_ah_options = '{"normalization_type": "L2"}');

存储列和预先过滤

如需进一步提高向量索引的效率,您可以指定基表中的列以存储在向量索引中。使用存储列可通过以下方式优化调用 VECTOR_SEARCH 函数的查询:

  • 您不必搜索整个表,而是可以对使用 WHERE 子句预先过滤基表的查询语句调用 VECTOR_SEARCH 函数。如果您的表具有索引,并且您仅过滤存储列,则 BigQuery 会在搜索之前过滤数据,然后使用索引搜索较小的结果集,从而优化查询。如果您过滤未存储的列,则 BigQuery 会在搜索表后应用过滤(即进行事后过滤)。

  • VECTOR_SEARCH 函数会输出名为 base 的结构体,其中包含基表中的所有列。如果没有存储列,则需要进行可能开销很大的联接来检索存储在 base 中的列。如果您使用 IVF 索引,并且您的查询仅从 base 中选择存储列,则 BigQuery 会优化查询以消除该联接。对于 TreeAH 索引,系统不会移除与基表的联接。TreeAH 索引中的存储列仅用于预过滤。

如需存储列,请在 CREATE VECTOR INDEX DDL 语句STORING 子句中列出这些列。存储列会增加向量索引的大小,因此最好仅存储最常使用或过滤后的列。

以下示例创建了一个具有存储列的向量索引,然后运行一个仅选择存储列的向量搜索查询:

-- Create a table that contains an embedding.
CREATE TABLE my_dataset.my_table(embedding ARRAY<FLOAT64>, type STRING, creation_time DATETIME, id INT64);

-- Create a query table that contains an embedding.
CREATE TABLE my_dataset.my_testdata(embedding ARRAY<FLOAT64>, test_id INT64);

-- Create a vector index with stored columns.
CREATE VECTOR INDEX my_index ON my_dataset.my_table(embedding)
STORING (type, creation_time)
OPTIONS (index_type = 'IVF');

-- Select only stored columns from a vector search to avoid an expensive join.
SELECT query, base.type, distance
FROM
  VECTOR_SEARCH(
    TABLE my_dataset.my_table,
    'embedding'
    TABLE my_dataset.my_testdata);

预过滤器和后过滤器

在 BigQuery VECTOR_SEARCH 运算中,预过滤和后过滤都用于根据与向量嵌入关联的元数据列应用条件,以优化搜索结果。为了优化查询性能、费用和准确性,请务必了解它们之间的差异、实现方式和影响。

预过滤和后过滤的定义如下:

  • 预过滤:在近似最近邻 (ANN) 搜索对候选向量执行距离计算之前应用过滤条件。这会缩小搜索期间考虑的矢量池。因此,由于 ANN 搜索会评估的潜在候选项更少,预过滤通常会缩短查询时间并降低计算开销。
  • 后期过滤:在 ANN 搜索确定初始 top_k 个最近邻后应用过滤条件。这会根据指定的条件优化最终结果集。

WHERE 子句的位置决定了过滤器是作为前置过滤器还是后置过滤器。

如需创建预过滤条件,查询的 WHERE 子句必须应用于 VECTOR_SEARCH 函数的基表参数。谓词必须应用于存储列,否则它实际上会变成后置过滤条件。

以下示例展示了如何创建预过滤器:

-- Pre-filter on a stored column. The index speeds up the query.
SELECT *
FROM
  VECTOR_SEARCH(
    (SELECT * FROM my_dataset.my_table WHERE type = 'animal'),
    'embedding',
    TABLE my_dataset.my_testdata);

-- Filter on a column that isn't stored. The index is used to search the
-- entire table, and then the results are post-filtered. You might see fewer
-- than 5 matches returned for some embeddings.
SELECT query.test_id, base.type, distance
FROM
  VECTOR_SEARCH(
    (SELECT * FROM my_dataset.my_table WHERE id = 123),
    'embedding',
    TABLE my_dataset.my_testdata,
    top_k => 5);

-- Use pre-filters with brute force. The data is filtered and then searched
-- with brute force for exact results.
SELECT query.test_id, base.type, distance
FROM
  VECTOR_SEARCH(
    (SELECT * FROM my_dataset.my_table WHERE id = 123),
    'embedding',
    TABLE my_dataset.my_testdata,
    options => '{"use_brute_force":true}');

如需创建后过滤条件,必须在 VECTOR_SEARCH 函数之外应用查询的 WHERE 子句,以便过滤搜索返回的结果。

以下示例展示了如何创建后置过滤器:

-- Use post-filters. The index is used, but the entire table is searched and
-- the post-filtering might reduce the number of results.
SELECT query.test_id, base.type, distance
FROM
  VECTOR_SEARCH(
    TABLE my_dataset.my_table,
    'embedding',
    TABLE my_dataset.my_testdata,
    top_k => 5)
WHERE base.type = 'animal';

SELECT base.id, distance
FROM
  VECTOR_SEARCH(
    TABLE mydataset.base_table,
    'embedding',
    (SELECT embedding FROM mydataset.query_table),
    top_k => 10
  )
WHERE type = 'document' AND year > 2022

当您使用事后过滤时,或者当您指定的基表过滤条件引用未存储的列并因此充当事后过滤条件时,如果谓词是选择性的,最终结果集可能包含的行数少于 top_k,甚至可能为零行。如果您需要过滤后获得特定数量的结果,请考虑指定较大的 top_k 值,或在 VECTOR_SEARCH 调用中增加 fraction_lists_to_search 值。

在某些情况下(尤其是预过滤器非常具有选择性的情况下),预过滤也可能会减小结果集的大小。如果发生这种情况,请尝试在 VECTOR_SEARCH 调用中增加 fraction_lists_to_search 值。

限制

  • 您不能在预先过滤中使用逻辑视图
  • 如果您的预先过滤包含子查询,则可能会干扰索引使用。
  • 如果基表中列的模式、类型或架构发生更改,并且是向量索引中存储的列,则可能会延迟一段时间才会在向量索引中反映此更改。在为索引应用更新之前,向量搜索查询会使用基表中已修改的存储列。
  • 当表的索引具有存储列时,如果从对该表进行的 VECTOR_SEARCH 查询的 query 输出中选择 STRUCT 类型的列,则整个查询可能会失败。

了解何时将数据编入索引

向量索引由 BigQuery 全代管式,并且会在编入索引的表发生变化时自动进行刷新。

索引编制是异步进行的。向基表添加新行与新行反映在索引中之间存在延迟。不过,VECTOR_SEARCH 函数仍会考虑所有行,不会漏掉未编入索引的行。该函数会使用索引搜索已编入索引的记录,并使用蛮力搜索方法搜索尚未编入索引的记录。

如果您在小于 10 MB 的表上创建向量索引,则系统不会填充该向量索引。同样,如果您从编入索引的表中删除数据,并且该表大小低于 10 MB,则系统会暂时停用向量索引。在这种情况下,向量搜索查询不使用该索引,并且 Job 资源的 vectorSearchStatistics 部分中的 indexUnusedReasons 代码为 BASE_TABLE_TOO_SMALL。在没有索引的情况下,VECTOR_SEARCH 会自动转为使用暴力破解来查找嵌入的最近邻。

如果您删除表中编入索引的列或重命名表本身,则向量索引会自动予以删除。

监控向量索引的状态

您可以通过查询 INFORMATION_SCHEMA 视图来监控向量索引的运行状况。以下视图包含有关向量索引的元数据:

向量索引示例

以下示例展示了位于项目 my_project 的数据集 my_dataset 中表的所有活跃向量索引。它包括索引名称、用于创建索引的 DDL 语句以及索引覆盖率百分比。如果编入索引的基表小于 10 MB,则系统不会填充其索引,在这种情况下,coverage_percentage 值为 0。

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

结果类似于以下内容:

+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+
| table_name | index_name | ddl                                                                                             | coverage_percentage |
+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+
| table1     | indexa     | CREATE VECTOR INDEX `indexa` ON `my_project.my_dataset.table1`(embeddings)                      | 100                 |
|            |            | OPTIONS (distance_type = 'EUCLIDEAN', index_type = 'IVF', ivf_options = '{"num_lists": 100}')   |                     |
+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+
| table2     | indexb     | CREATE VECTOR INDEX `indexb` ON `my_project.my_dataset.table2`(vectors)                         | 42                  |
|            |            | OPTIONS (distance_type = 'COSINE', index_type = 'IVF', ivf_options = '{"num_lists": 500}')      |                     |
+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+
| table3     | indexc     | CREATE VECTOR INDEX `indexc` ON `my_project.my_dataset.table3`(vectors)                         | 98                  |
|            |            | OPTIONS (distance_type = 'DOT_PRODUCT', index_type = 'TREE_AH',                                 |                     |
|            |            |          tree_ah_options = '{"leaf_node_embedding_count": 1000, "normalization_type": "NONE"}') |                     |
+------------+------------+-------------------------------------------------------------------------------------------------+---------------------+

向量索引列示例

以下查询会提取具有向量索引的列的相关信息:

SELECT table_name, index_name, index_column_name, index_field_path
FROM my_project.dataset.INFORMATION_SCHEMA.VECTOR_INDEX_COLUMNS;

结果类似于以下内容:

+------------+------------+-------------------+------------------+
| table_name | index_name | index_column_name | index_field_path |
+------------+------------+-------------------+------------------+
| table1     | indexa     | embeddings        | embeddings       |
| table2     | indexb     | vectors           | vectors          |
| table3     | indexc     | vectors           | vectors          |
+------------+------------+-------------------+------------------+

向量索引选项示例

以下查询会提取向量索引选项的相关信息:

SELECT table_name, index_name, option_name, option_type, option_value
FROM my_project.dataset.INFORMATION_SCHEMA.VECTOR_INDEX_OPTIONS;

结果类似于以下内容:

+------------+------------+------------------+------------------+-------------------------------------------------------------------+
| table_name | index_name | option_name      | option_type      | option_value                                                      |
+------------+------------+------------------+------------------+-------------------------------------------------------------------+
| table1     | indexa     | index_type       | STRING           | IVF                                                               |
| table1     | indexa     | distance_type    | STRING           | EUCLIDEAN                                                         |
| table1     | indexa     | ivf_options      | STRING           | {"num_lists": 100}                                                |
| table2     | indexb     | index_type       | STRING           | IVF                                                               |
| table2     | indexb     | distance_type    | STRING           | COSINE                                                            |
| table2     | indexb     | ivf_options      | STRING           | {"num_lists": 500}                                                |
| table3     | indexc     | index_type       | STRING           | TREE_AH                                                           |
| table3     | indexc     | distance_type    | STRING           | DOT_PRODUCT                                                       |
| table3     | indexc     | tree_ah_options  | STRING           | {"leaf_node_embedding_count": 1000, "normalization_type": "NONE"} |
+------------+------------+------------------+------------------+-------------------------------------------------------------------+

验证向量索引使用情况

运行向量搜索查询的作业的作业元数据中提供了有关向量索引使用情况的信息。您可以使用 Google Cloud 控制台、bq 命令行工具、BigQuery API 或客户端库查看作业元数据

使用 Google Cloud 控制台时,您可以在向量索引使用模式未使用向量索引的原因字段中找到向量索引使用情况信息。

使用 bq 工具或 BigQuery API 时,您可以在 Job 资源的 VectorSearchStatistics 部分中找到向量索引使用情况信息。

索引使用模式通过提供以下值之一来指示是否使用了向量索引:

  • UNUSED:未使用向量索引。
  • PARTIALLY_USED:查询中的某些 VECTOR_SEARCH 函数使用向量索引,某些函数则不使用。
  • FULLY_USED:查询中的每个 VECTOR_SEARCH 函数都使用一个向量索引。

当索引使用模式值为 UNUSEDPARTIALLY_USED 时,未使用索引的原因会指明没有在查询中使用向量索引的原因。

例如,bq show --format=prettyjson -j my_job_id 返回的以下结果表明,由于在 VECTOR_SEARCH 函数中指定了 use_brute_force 选项,因此未使用索引:

"vectorSearchStatistics": {
  "indexUnusedReasons": [
    {
      "baseTable": {
        "datasetId": "my_dataset",
        "projectId": "my_project",
        "tableId": "my_table"
      },
      "code": "INDEX_SUPPRESSED_BY_FUNCTION_OPTION",
      "message": "No vector index was used for the base table `my_project:my_dataset.my_table` because use_brute_force option has been specified."
    }
  ],
  "indexUsageMode": "UNUSED"
}

索引管理选项

要创建索引并让 BigQuery 维护它们,您有两种选择:

  • 使用默认共享槽池:当计划编入索引的数据低于每个组织的限制时,您可以使用免费共享槽池来管理索引。
  • 使用您自己的预留:要在较大的生产工作负载上实现更可预测且一致的索引编制进度,您可以使用自己的预留来管理索引。

使用共享槽

如果您尚未将项目配置为使用专用预留来执行索引操作,就会在免费的共享槽池中处理索引管理,但存在以下限制。

如果向表添加数据,从而导致编入索引的表的总大小超过组织的限制,则 BigQuery 会暂停所有编入索引的表的索引管理。发生这种情况时,INFORMATION_SCHEMA.VECTOR_INDEXES 视图中的 index_status 字段会显示 PENDING DISABLEMENT,且该索引会排队等待删除。虽然索引正在等待停用,但它仍然在查询中使用,并且您需要为该索引支付存储费用。索引删除后,index_status 字段会将该索引显示为 TEMPORARILY DISABLED。在此状态下,查询不使用该索引,并且您不需要为该索引支付存储费用。在这种情况下,IndexUnusedReason 代码BASE_TABLE_TOO_LARGE

如果您从表中删除数据,并且编入索引的表的总大小低于每个组织的限制,则所有已编入索引的表的索引管理功能都将恢复。INFORMATION_SCHEMA.VECTOR_INDEXES 视图中的 index_status 字段为 ACTIVE,查询可以使用该索引,并且您需要为该索引支付存储费用。

BigQuery 不保证共享池的可用容量或您看到的索引吞吐量。对于生产应用,您可能需要使用专用槽来执行索引处理功能。

使用您自己的预留

您可以选择指定使用自己的预留来将表编入索引,而不是使用默认的共享槽池。使用您自己的预留可确保索引管理作业(例如创建、刷新和后台优化)具有可预测且一致的性能。

  • 在预留中运行索引作业时,没有表大小限制。
  • 使用您自己的预留可以在管理索引时更加灵活。 如果需要创建非常大的索引或对编入索引的表进行大量更新,您可以暂时为分配空间添加更多的槽。

如需将具有指定预留的项目中的表编入索引,请在表所在的区域中创建预留。然后,将项目分配到该预留,并将 job_type 设置为 BACKGROUND

SQL

使用 CREATE ASSIGNMENT DDL 语句.

  1. 在 Google Cloud 控制台中,前往 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 语句的速率
  • 构建和维护索引的可接受延迟时间
  • 索引的复杂程度,通常由数据属性(例如重复字词数量)决定
监控用量和进度

评估高效地运行索引管理作业所需的槽数的最佳方法是监控槽利用率并相应地调整预留大小。以下查询生成索引管理作业的每日槽使用量。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 从头开始重新构建索引。为避免产生不同步索引,请确保您有足够的槽来支持数据注入和优化中的索引更新。如需详细了解如何监控槽使用量,请参阅管理员资源图表

删除向量索引

当您不再需要向量索引或想要更改表中编入索引的列时,可以使用 DROP VECTOR INDEX DDL 语句删除该表上的索引。

例如:

DROP VECTOR INDEX my_index ON my_dataset.indexed_table;

如果删除编入索引的表,其索引也会自动删除。

后续步骤