创建索引和查询向量

本页介绍了如何使用存储的嵌入生成索引,以及如何使用 AlloyDB for PostgreSQL 通过 ScaNNIVFIVFFlatHNSW 索引查询嵌入。如需详细了解如何存储嵌入,请参阅存储向量嵌入

准备工作

在开始创建索引之前,您必须满足以下前提条件。

  • 嵌入矢量会添加到 AlloyDB 数据库中的表中

  • 安装了由 Google 为 AlloyDB 扩展的基于 pgvectorvector 扩展版本 0.5.0 或更高版本。

    CREATE EXTENSION IF NOT EXISTS vector;
    
  • 如需生成 ScaNN 索引,请安装 vector 扩展程序以及 alloydb_scann 扩展程序。

    CREATE EXTENSION IF NOT EXISTS alloydb_scann;
    

创建索引

您可以为数据库中的表创建以下索引类型之一。

创建 ScaNN 索引

AlloyDB alloydb_scann,由 Google 开发的 PostgreSQL 扩展程序,可实现由 ScaNN 算法提供支持的高效最近邻索引。

ScaNN 索引是一种基于树的量化索引,用于近似最近邻搜索。与 HNSW 相比,它可缩短索引构建时间并减小内存占用空间。此外,与 HNSW 相比,它可根据工作负载提供更快的 QPS。

两级树 ScaNN 索引

如需使用 ScaNN 算法将两级树索引应用于包含存储的向量嵌入的列,请运行以下 DDL 查询:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE);

替换以下内容:

  • INDEX_NAME:您要创建的索引的名称,例如 my-scann-index。索引名称会在数据库中共享。确保每个索引名称在数据库中对应于每个表的唯一名称。

  • TABLE:要向其中添加索引的表。

  • EMBEDDING_COLUMN:用于存储 vector 数据的列。

  • DISTANCE_FUNCTION:要与此索引搭配使用的距离函数。请按以下方式之一操作:

    • L2 距离l2

    • 点积dot_product

    • 余弦距离cosine

  • NUM_LEAVES_VALUE:要应用于此索引的分区数量。设置为 1 到 1048576 之间的任意值。如需详细了解如何确定此值,请参阅调整 ScaNN 索引

三级树 ScaNN 索引

如需使用 ScaNN 算法为包含存储的向量嵌入的列创建三级树索引,请运行以下 DDL 查询:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (EMBEDDING_COLUMN DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

替换以下内容:

  • MAX_NUM_LEVELS:K 均值聚类树的层数上限。对于基于树的两级量化,请将其设置为 1(默认值);对于基于树的三级量化,请将其设置为 2

创建索引后,您可以按照使用给定文本执行最近邻查询中的说明,运行利用该索引的最近邻搜索查询。

必须设置索引参数,以便在 QPS 和召回率之间取得适当的平衡。如需详细了解如何调整 ScaNN 索引,请参阅调整 ScaNN 索引

如需在使用 real[] 数据类型(而非 vector)的嵌入列上创建此索引,请将该列转换为 vector 数据类型:

CREATE INDEX INDEX_NAME ON TABLE
  USING scann (CAST(EMBEDDING_COLUMN AS vector(DIMENSIONS)) DISTANCE_FUNCTION)
  WITH (num_leaves=NUM_LEAVES_VALUE, max_num_levels = MAX_NUM_LEVELS);

DIMENSIONS 替换为嵌入列的维度宽度。如需详细了解如何查找维度,请参阅矢量函数中的 vector_dims 函数。

如需查看索引编制进度,请使用 pg_stat_progress_create_index 视图:

SELECT * FROM pg_stat_progress_create_index;

phase 列会显示索引创建的当前状态,索引创建后,building index: tree training 阶段会消失。

如需针对目标召回率和 QPS 平衡调整索引,请参阅调整 ScaNN 索引

运行查询

将嵌入存储在数据库中并为其编制索引后,您就可以开始使用 pgvector 查询功能进行查询了。您无法使用 alloydb_scann 扩展程序运行批量搜索查询。

如需查找嵌入向量的最近邻语义,您可以运行以下示例查询,并在其中设置与在创建索引期间使用的距离函数相同的距离函数。

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN DISTANCE_FUNCTION_QUERY ['EMBEDDING']
    LIMIT ROW_COUNT

替换以下内容:

  • TABLE:包含要与文本进行比较的嵌入的表。

  • INDEX_NAME:您要使用的索引的名称,例如 my-scann-index

  • EMBEDDING_COLUMN:包含存储的嵌入的列。

  • DISTANCE_FUNCTION_QUERY:要与此查询搭配使用的距离函数。根据创建索引时使用的距离函数,选择以下任一选项:

    • L2 距离<->

    • 内积<#>

    • 余弦距离<=>

  • EMBEDDING:您要查找其最近的已存语义邻居的嵌入向量。

  • ROW_COUNT:要返回的行数。

    如果您只希望返回单个最佳匹配项,请指定 1

如需详细了解其他查询示例,请参阅查询

您还可以使用 embedding() 函数将文本转换为向量。您可以将该向量应用于 pgvector 中的某个最近邻运算符(<-> 表示 L2 距离),以查找语义上最相似的嵌入数据库行。

由于 embedding() 会返回 real 数组,因此您必须将 embedding() 调用显式转换为 vector,才能将这些值与 pgvector 运算符搭配使用。

  CREATE EXTENSION IF NOT EXISTS google_ml_integration VERSION '1.2';
  CREATE EXTENSION IF NOT EXISTS vector;

  SELECT * FROM TABLE
    ORDER BY EMBEDDING_COLUMN::vector
    <-> embedding('MODEL_IDVERSION_TAG', 'TEXT')
    LIMIT ROW_COUNT

替换以下内容:

  • MODEL_ID:要查询的模型的 ID。

    如果您使用的是 Vertex AI Model Garden,请将 text-embedding-005 指定为模型 ID。这些是 AlloyDB 可用于文本嵌入的云端模型。如需了解详情,请参阅文本嵌入

  • 可选:VERSION_TAG:要查询的模型的版本标记。在该标记前面加上 @

    如果您将 text-embedding-005 英语模型之一与 Vertex AI 搭配使用,请指定 模型版本中列出的某个版本标记,例如 text-embedding-005

    Google 强烈建议您始终指定版本标记。如果您未指定版本标记,AlloyDB 将始终使用最新的模型版本,这可能会导致意外结果。

  • TEXT:要转换为向量嵌入的文本。

后续步骤