Skip to content

CREATE INDEX USING IVFFLAT

语法说明

向量索引可用于加速对包含向量列的表的 KNN(K-Nearest Neighbors)查询。Matrixone 目前支持具有 l2_distance 度量的 IVFFLAT 向量索引。

我们可以指定 PROBE_LIMIT 来决定要查询的聚类中心数量。PROBE_LIMIT 默认为 1,即仅扫描 1 个聚类中心。但如果您将其设置为更高的值,它会扫描更多数量的聚类中心和向量,这使得性能可能会下降一点,但准确率会上升。我们可以指定适当的探针数量来平衡查询速度和召回率。PROBE_LIMIT 的理想值为:

  • 如果总行数<1000000:PROBE_LIMIT=总行数/10
  • 如果总行数>1000000:PROBE_LIMIT=sqrt(总行数)

语法结构

> CREATE INDEX index_name
USING IVFFLAT
ON tbl_name (col,...)
LISTS=lists 
OP_TYPE "vector_l2_ops"

语法释义

  • index_name:索引名称
  • IVFFLAT:向量索引类型,目前支持 vector_l2_ops
  • lists:索引中所需的分区数,必须大于 0
  • OP_TYPE:要使用的距离度量

NOTE:

  • LISTS 的理想值为:
    • 如果总行数<1000000:lists=总行数/1000
    • 如果总行数>1000000:lists=sqrt(总行数)
  • 建议在数据填充完毕后再创建索引,如果在空表上创建向量索引,则所有向量量都将映射到一个分区,随着时间的推移,数据量不断增长,导致索引变得越来越大,查询性能会下降。

示例

--需设置参数 experimental_ivf_index 值为 1(默认 0)才能使用向量索引
SET GLOBAL experimental_ivf_index = 1;
drop table if exists t1;
create table t1(coordinate vecf32(2),class char);
-- 有七个点,每个点代表其在 x 和 y 轴上的坐标,并且每个点的 class 被标记为 A 或 B。
insert into t1 values("[2,4]","A"),("[3,5]","A"),("[5,7]","B"),("[7,9]","B"),("[4,6]","A"),("[6,8]","B"),("[8,10]","B");
--创建向量索引
create index idx_t1 using ivfflat on t1(coordinate)  lists=1 op_type "vector_l2_ops";

mysql> show create table t1;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                           |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
`coordinate` VECF32(2) DEFAULT NULL,
`class` CHAR(1) DEFAULT NULL,
KEY `idx_t1` USING ivfflat (`coordinate`) lists = 1  op_type 'vector_l2_ops' 
) |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

mysql> show index from t1;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+-----------------------------------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Index_params                            | Visible | Expression |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+-----------------------------------------+---------+------------+
| t1    |          1 | idx_t1   |            1 | coordinate  | A         |           0 | NULL     | NULL   | YES  | ivfflat    |         |               | {"lists":"1","op_type":"vector_l2_ops"} | YES     | NULL       |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+-----------------------------------------+---------+------------+
1 row in set (0.01 sec)

--设置扫描的聚类中心数量
SET @PROBE_LIMIT=1;
--现在,我们有一个新点,其坐标为 (4, 4),我们想要使用 KNN 查询来预测这个点的类别。
mysql> select * from t1 order by l2_distance(coordinate,"[4,4]") asc;
+------------+-------+
| coordinate | class |
+------------+-------+
| [3, 5]     | A     |
| [2, 4]     | A     |
| [4, 6]     | A     |
| [5, 7]     | B     |
| [6, 8]     | B     |
| [7, 9]     | B     |
| [8, 10]    | B     |
+------------+-------+
7 rows in set (0.01 sec)

--根据查询结果可预测这个点的类别为 A

限制

一次只支持在一个向量列上建立向量索引,如需在多个向量列上建立向量索引,可多次执行创建语句。