-
Notifications
You must be signed in to change notification settings - Fork 171
向量索引使用
liguoqiang edited this page Jan 4, 2024
·
2 revisions
CREATE TABLE `t_vec` (
`id` int(10) NOT NULL ,
`vec` varchar(1024) NOT NULL , //向量,使用逗号分割字符串表示,0.16,0.32,0.002。。。
`__weight` float NULL , // 每次请求返回距离
`id2` int(10) NOT NULL ,
PRIMARY KEY (`id`,`id2`) COMMENT '{"index_state":"IS_PUBLIC", "hint_status":"IHS_NORMAL"}',
VECTOR KEY `idx` (`vec`) COMMENT '{"vector_description":"HNSW16", "dimension":16, "nprobe":5, "metric_type":"METRIC_L2"}'
) ENGINE=Rocksdb DEFAULT CHARSET=gbk AVG_ROW_LENGTH=200 COMMENT='{"resource_tag":"", "replica_num":3, "region_split_lines":524288, "namespace":"TEST"}'
PARTITION BY RANGE(id2) // 目前partition字段必须包含在主键里
(
PARTITION p1 VALUES [1, 2),
PARTITION p2 VALUES [2, 3),
PARTITION p3 VALUES [3, 4)
);
// 对于分区表可以无损增加分区
ALTER TABLE t_vec ADD PARTITION p4 VALUES [4, 5);
建表可选特殊字段表示距离,每次运行后返回的数据会实时填这两个字段
`__weight` float NULL, //返回距离,类型不能错,不能写double
'{"vector_description":"HNSW16", "dimension":16, "nprobe":5,"efsearch":16,"efconstruction":40, "metric_type":"METRIC_L2"}'
- VECTOR KEY表示向量索引,内部使用faiss库:https://github.com/facebookresearch/faiss/
- dimension:向量维度,必填,文心一言是384维,chatgpt是1536维
- vector_description:可以描述索引类型,目前只支持:FLAT,HNSWx(x建议16)三种索引,不填默认是HNSW16
- metric_type:距离表示,默认METRIC_L2(https://github.com/facebookresearch/faiss/wiki/MetricType-and-distances)
- METRIC_L2(默认值):Faiss报告平方欧几里得(L2)距离,避免了平方根。这仍然是单调的欧几里得距离,但如果需要精确的距离,则需要对结果进行额外的平方根运算。该度量不受数据旋转(正交矩阵变换)的影响。__weight范围0~1
- METRIC_INNER_PRODUCT:这通常用于推荐系统中最大内积搜索。查询向量的范数不会影响结果排名(当然数据库向量的范数很重要)。除非向量被归一化(位于单位超球面上;请参见下文余弦相似性),否则它本身并不是余弦相似性。
- 余弦相似度:依然选METRIC_INNER_PRODUCT,向量需要做归一化,vector_description加上L2norm,前缀,比如HNSW16索引,改成L2norm,HNSW16;erniebot embedding后已经是归一化,不需要加L2norm。__weight范围-1~+1
- nprobe:IVF前缀索引时,表示搜索的质点数,默认5
- efsearch:HNSW查询期间要访问的最近邻居的数量,默认是16
- efconstruction:HNSW构建索引期间要访问的最近邻居的数量,默认是40
向量比较暂时复用match against语法,match(vector_field) against ('0.1,0.2,0.3...' in vector mode) 常规查询:查询top 10的向量
- select * from table where match(vector_field) against ('0.1,0.2,0.3...' in vector mode) order by __weight asc limit 10; // METRIC_L2用asc,METRIC_INNER_PRODUCT用desc 组合其他条件
- where match(vector_field) against ('0.1,0.2,0.3...' in vector mode) and tag = 3 支持partition
- select * from table partition(p0) where match(vector_field) against ('0.1,0.2,0.3...' in vector mode) order by __weight asc limit 10; // METRIC_L2用asc,METRIC_INNER_PRODUCT用desc
语法与普通表相同,向量使用逗号分割字符串表示,分割出的数量必须与dimension相等 insert into table (id, name, vec) values (1, 'abc', '0.163,0.182,...');
- FLAT:不需要train,直接按行插入
- IVFxPQy(任意IVF+其他):引入FLAT层,1000行批量插入,新增超过20000(阈值),则train+add index
- HNSWx:支持批量add,引入FLAT层,1000行批量插入
语法与普通表相同:delete from table where id=3;
语法与普通表相同:
- update table set name='xxx' where id=3; 更新非向量字段,不改变向量索引
- update table set vector_field='0.3,0.4,...' where id=3; 更新向量字段,会转化未删除索引/插入索引两个步骤