AlloyDB for PostgreSQL 中的 ScaNN 索引调优的最佳实践

ScaNN 索引的建议参数因您选择构建二级树索引还是三级树索引而异。本页面提供了有关如何对 AlloyDB for PostgreSQL 索引参数进行调优以在召回率和 QPS 之间取得最佳平衡的建议。

ScaNN 索引创建

如需了解详情,请参阅 ScaNN 索引参考文档

二级树索引

如需应用建议以帮助您为数据集找到 num_leavesnum_leaves_to_search 的最佳值,请按照以下建议的步骤操作:

  1. 如需创建针对以下情况优化的 ScaNN 索引,请将 num_leaves 参数设置为以下的相应值,其中 rows 是已编入索引的表中的行数:
    • 实现平衡的索引构建时间和质量:将 num_leaves 设置为 sqrt(rows)
    • 高质量:将 num_leaves 设置为 rows/100。
  2. 运行测试查询,并增加 scann.num_of_leaves_to_search 的值,直到达到目标召回率范围(例如 95%)为止。如需详细了解如何分析查询,请参阅分析查询
  3. 记下 scann.num_leaves_to_searchnum_leaves 之间的比率,此比率将在后续步骤中使用。此比率可提供关于数据集的近似值,有助于您实现目标召回率。

    如果您使用的是高维向量(500 个维度或更高),并且想要提高召回率,请尝试对 scann.pre_reordering_num_neighbors 的值进行调优。默认值设置为值 500 * K,其中 K 是您在查询中设置的限制。
  4. 如果您的查询达到目标召回率后 QPS 过低,请按照以下步骤操作:
    1. 重新创建索引,并根据以下指导增加 num_leavesscann.num_leaves_to_search 的值:
      • num_leaves 设置为行数平方根的更大倍数。例如,如果索引的 num_leaves 设置为行数的平方根,请尝试将其设置为平方根的两倍。如果该值已是两倍,请尝试将其设置为平方根的三倍。
      • 根据需要增加 scann.num_leaves_to_search,以使其与 num_leaves 保持您在第 3 步中记录的比率。
      • num_leaves 设置为小于或等于行数除以 100 的值。
    2. 再次运行测试查询。在运行测试查询时,尝试减少 scann.num_leaves_to_search,找到一个可以增加 QPS,同时保持较高召回率的值。在不重建索引的情况下尝试使用不同的 scann.num_leaves_to_search 值。
  5. 重复第 4 步,直到 QPS 和召回率范围都达到可接受的值。

三级树索引

除了针对二级树 ScaNN 索引的建议之外,还请遵循以下指导。

如需应用建议以查找 num_leavesmax_num_levels 索引参数的最佳值,请按照以下步骤操作:

  1. 根据您的性能目标,使用以下 num_leavesmax_num_levels 组合创建 ScaNN 索引:

    • 平衡索引构建时间和质量:将 max_num_levels 设置为 2,将 num_leaves 设置为 power(rows, ⅔)
    • 优化质量:将 max_num_levels 设置为 2,将 num_leaves 设置为 rows/100
  2. 运行测试查询。如需详细了解如何分析查询,请参阅分析查询

  3. 记下 scann.num_leaves_to_searchnum_leaves 之间的比率,此比率将在后续步骤中使用。此比率可提供关于数据集的近似值,有助于您实现目标召回率。

如果您使用的是高维向量(500 个维度或更高),并且想要提高召回率,请尝试对 scann.pre_reordering_num_neighbors 的值进行调优。默认值设置为值 500 * K,其中 K 是您在查询中设置的限制。

  1. 如果您的查询达到目标召回率后 QPS 过低,请按照以下步骤操作:

    • 重新创建索引,并根据以下指导增加 num_leavesscann.num_leaves_to_search 的值:
    • num_leaves 设置为 power(rows, ⅔) 的更大倍数。例如,如果索引的 num_leaves 设置为 power(rows, ⅔),请尝试将其设置为 power(rows, ⅔) 的两倍。如果该值已经是两倍,请尝试将其设置为 power(rows, ⅔) 的三倍。
    • 根据需要增加 scann.num_leaves_to_search,以使其与 num_leaves 保持您在第 3 步中记录的比率。
    • num_leaves 设置为小于或等于 rows/100 的值。
    • 再次运行测试查询。在运行测试查询时,尝试减少 scann.num_leaves_to_search,找到一个可以增加 QPS,同时保持较高召回率的值。在不重建索引的情况下尝试使用不同的 scann.num_leaves_to_search 值。
  2. 重复第 4 步,直到 QPS 和召回率范围都达到可接受的值。

提高过滤搜索的召回率

在执行包含过滤条件的 k 最近邻 (KNN) 向量搜索时,您可能会遇到查询返回的结果数量少于 LIMIT 子句中请求的数量的情况。这可能会导致所谓的召回率不足,并且在使用高度选择性的过滤条件时更有可能发生这种情况。这是因为 ScaNN 搜索的初始分区或叶不包含足够多的满足过滤条件的向量。

为了解决这个问题,AlloyDB 提供了一项功能,可让搜索动态扩展到初始叶集之外,以找到足够多的匹配结果。

流式传输的运作方式

您可以通过将 scann.satisfy_limit 参数设置为 relaxed_order 来启用流式传输功能。启用后,向量扫描会继续搜索其他叶分区,直到找到足够的结果来满足查询的 LIMIT,从而提高召回率。

为防止搜索持续时间过长并控制性能影响,您可以使用 scann.max_pct_leaves_to_search 参数。此设置可为查询可访问的叶节点的总百分比设置上限,从而起到保护作用。此属性的默认值为 15%

何时使用流式传输

在以下情况下,请考虑使用流式传输功能:

  • 您可以在向量搜索中使用过滤条件。
  • 您发现,根据 LIMIT 子句,查询返回的结果数量比预期少。

启用 scann.satisfy_limit 后,您可以提高过滤后搜索的召回率。建议您同时配置 scann.max_pct_leaves_to_search,以在召回率和查询性能之间取得平衡。

索引维护

如果您的表容易频繁更新或插入,我们建议您定期重新编制现有的 ScaNN 索引,以提高召回率准确率。您可以监控索引指标,以查看自构建索引以来向量分布或向量变更的变化,然后相应地重新编制索引。如需详细了解指标,请参阅查看向量索引指标

后续步骤