排查 ScaNN 索引错误

本文档介绍了生成 ScaNN 索引时可能会遇到的错误。还提供了错误示例和建议的修复方法。

错误列表

以下是尝试创建 ScaNN 索引时生成的错误列表。您可以停用生成这些错误的功能,并继续生成索引。如需了解详情,请参阅强制创建索引并抑制错误

ERROR: Cannot create ScaNN index with empty table

错误消息

当您尝试为没有数据的表生成索引,或尝试截断已生成 ScaNN 索引的表时,会发生以下错误:

ERROR: Cannot create ScaNN index with empty table. Once the table is populated with data, create the index. See documentation to bypass this validation.

导致错误的查询示例

  • 查询示例 A

    create table t1 (a INT, b VECTOR(512));
    CREATE TABLE
    create index on t1 using ScaNN(b cosine) with (num_leaves = 10, quantizer = 'sq8');
    
  • 查询示例 B

    truncate t1;
    

在生成 ScaNN 索引之前,请确保您的表已填充嵌入矢量。

错误:无法创建 ScaNN 索引

错误消息

当您尝试为填充的行数较少的表生成索引时,会发生以下错误:

Cannot create ScaNN index, error: INVALID_ARGUMENT: Number of row (5) must be larger than (1000).

导致错误的查询示例

create table t1 (a INT, b VECTOR(512));
CREATE TABLE
insert into t1 select (random()*1e9)::int, random_vector(512) from generate_series(1, 5);
INSERT 0 5
create index on t1 using scann(b cosine) with (num_leaves = 100, quantizer = 'sq8');

在生成 ScaNN 索引之前,请确保您的表已填充嵌入矢量。我们建议表中的行数大于 num_leaves 参数中定义的值。

错误:无法在父分区表上创建 ScaNN 索引。

错误消息

如果您已基于父表创建分区表,则在父表上创建 ScaNN 索引会生成以下错误:

ERROR: Cannot create ScaNN index on parent partition table. Create ScaNN indexes on the child tables instead. See documentation to bypass this validation.

导致错误的查询示例

create table t1 (a INT, b VECTOR(512)) partition by range(a);
CREATE TABLE
CREATE TABLE t1_one_ten PARTITION of t1 for values from (1) to (10);
CREATE TABLE
insert into t1_one_ten select (random()*1e9)::int, random_vector(512) from generate_series(1, 100);
INSERT 0 100
CREATE TABLE t1_eleven_twenty PARTITION of t1 for values from (11) to (20);
CREATE TABLE
insert into t1_eleven_twenty select (random()*1e9)::int, random_vector(512) from generate_series(1, 100);
INSERT 0 100
create index on t1 using scann(b cosine) with (num_leaves = 10, quantizer = 'sq8');

您无法在分区表的父表上生成 ScaNN 索引。您必须在分区表上生成 ScaNN 索引。

强制创建索引并抑制错误

您可以强制 AlloyDB 生成索引并抑制错误。在允许使用此方法生成索引之前,请考虑以下影响:

  • 由于索引是基于较少或无数据进行训练的,因此质心学习基于零数据,导致召回率较低。
  • 写入数据库的性能也可能会较慢。

如需强制生成索引,请完成以下操作:

  1. 在数据库上将 scann.allow_blocked_operations creation 会话级参数设置为 true

    SET scann.allow_blocked_operations = true;
    
  2. 向将对数据库运行这些查询的用户分配 SUPERUSER 权限:

    CREATE USER USER_NAME WITH SUPERUSER PASSWORD PASSWORD;
    

    替换以下内容:

    • USER_NAME:您要向其授予特权的用户的名称。
    • PASSWORD:用户的密码。