• 热门
  • 基础
  • 数据库
  • 安全
  • 大数据
  • 人工智能
  • 混合云
  • 开发与运维
  • 企业应用

应用服务

行业引擎

全部文档
当前文档

暂无内容

如果没有找到您期望的内容,请尝试其他搜索词

文档中心

用户指南

最近更新时间:2024-11-26 20:01:31

向量表

向量表即存储向量数据的表。本节将通过具体示例演示如何创建向量表。所有示例中使用的语法均遵循 SQL:1999 标准,并兼容部分 SQL:2003 特性。

前提条件

  • 环境中存在向量版数仓服务单元。

  • 该向量版数仓服务单元中存在至少一个数据库。

语法

CREATE TABLE <table_name>
(  
    C1 <data_type>,  
    C2 <data_type>,  
    ......,  
    CN <vector_type>(128), 
    PRIMARY KEY (<col_name1>[, <col_name2>, ... , <col_nameN>])
) DISTRIBUTED BY (C1);

表中的向量列(<vector_type>)括号中的数字表示向量的维度,即 <vector_type>(128) 表示向量维度为 128。下表描述了 Relyt Vector DPS 支持的向量列数据类型:

数据类型

描述

vecf16

数据类型为 16 位浮点数组,float16[]

vector

数据类型为 32 位浮点数组,float32[]

vector 相比,vecf16 不仅存储成本小一倍,同时计算性能快一倍,且准度相同,因此更为推荐使用。

示例

执行如下命令,创建一个名为 FACE_TABLE 的堆表,其中 C1 为主键,`C4` 为向量列。

CREATE TABLE FACE_TABLE (  
    C1 INT,
    C2 TIMESTAMP NOT NULL,
    C3 VARCHAR(20) NOT NULL,
    C4 VECF16(512) NOT NULL
    PRIMARY KEY (C1)
) DISTRIBUTED BY (C1);

使用分区表管理增量数据

对于具备时间属性的数据(例如数据按时间维度导入,保留 N 天,超出时间过期),可以使用 PARTITION BY 语句将表划分成多个子表,可以对子表单独进行导入和 TRUNCATE,从而支持增量的表数据管理。

如下为示例语句:

CREATE TABLE test_tbl
(
  C1                  VARCHAR,
  C2                  VECF16(512),
  post_publish_time   TIMESTAMP
)
DISTRIBUTED BY (C1)
PARTITION BY RANGE (post_publish_time) (START (DATE '2024-08-01') INCLUSIVE END (DATE '2024-08-31') EXCLUSIVE EVERY(INTERVAL '1 day'), DEFAULT PARTITION extra);

向量索引

在处理大型数据集或需要快速访问和检索数据的场景(数据库查询优化、机器学习和数据挖掘、图像和视频检索、空间数据查询等)中,创建向量索引是加速向量检索的有效方式,可以提高查询性能、加速数据分析和优化搜索任务,从而提高系统的效率和响应速度。

背景介绍

Vector DPS 采用了主流的 HNSW(Hierarchical Small World Graph)算法,将 skip list 的概念与 NSW(Navigable Small World)图相结合,通过分层结构实现了高效的近似最近邻搜索。在该结构中,上层包含较长的边,用于快速定位目标,而下层则包含较短的边,以提升搜索精度。

在构建图时,可以通过调整参数m 来控制新节点与其最近邻节点的连接数量。较高的m 值会使图结构更加密集,节点之间的连接增多,从而提升搜索性能,但同时会增加内存消耗并延长插入时间。在节点插入时,算法会找到最近的m 个节点,并与它们建立双向连接。

此外,Vector DPS 还支持量化(Product Quantization,PQ)功能,可对高维向量进行降维处理。通过在索引中存储降维后的向量,可以减少回表操作的次数,从而提高向量插入和查询时的检索性能。

语法

CREATE INDEX <index_name>
ON <schema_name>.<table_name>
USING vectors (<column_name> <distance_measure>) 
WITH (options = $$
<common_option_key1> = <common_option_value1>
<common_option_key2> = <common_option_value2>
...
[indexing.hnsw]
<hnsw_option_key1> = <hnsw_option_value1>
<hnsw_option_key2> = <hnsw_option_value2>
...
$$);

参数说明

1. <index_name>

索引名称,为可选参数。

2. <schema_name>

Schema 名称。

3. <table_name>

表名称。

4. <column_name>

向量索引列名称。

5. <distance_measure>

相似度距离度量算法,其表示形式为 <vector_data_type>_<distance_type>_ops。可选值包括:

  • vecf16_l2_ops: 16 位浮点数类型的平方欧式距离

  • vecf16_dot_ops: 16 位浮点数类型的负点积距离

  • vecf16_cos_ops: 16 位浮点数类型的余弦距离

  • vector_l2_ops: 32 位浮点数类型的平方欧式距离

  • vector_dot_ops: 32 位浮点数类型的负点积距离

  • vector_cos_ops: 32 位浮点数类型的余弦距离

  1. 其它可选通用向量索引参数(<common_option_n>)说明如下表所示:

类型

取值范围

默认值

说明

optimizing.optimizing_threads

integer

[1, 65535]

1

构建索引的最大线程数。

optimizing.sealing_secs

integer

[1, 60]

60

构建索引合并探测时间。

segment.max_growing_segment_size

integer

[1, 4_000_000_000]

20_000

未创建索引的向量的最大大小。

segment.max_sealed_segment_size

integer

[1, 4_000_000_000]

1_000_000

用于索引创建的向量的最大大小。

  1. HNSW 算法的相关参数(HNSW_OPTION)说明如下表所示:

类型

取值范围

默认值

说明

m

integer

[4, 128]

12

节点的最大度数。

ef_construction

integer

[10, 2000]

300

构建中的搜索范围。

quantization

table

trivial、scalar 或product

N/A

可选值为:trivial:不使用量化 scalar:使用标量量化product:使用乘积量化(推荐)计算距离使用的量化算法。

quantization.product 的选项:

类型

取值范围

默认值

说明

sample

integer

[1, 1_000_000]

65535

用于量化的样本。

ratio

enum

“x4”、“x8”、“x16”、“x32”、“x64”

"x4"

量化的压缩比。

示例

假设有一个文本知识库,将文章分割成块(Chunk)后,转换为 512 维的 Embedding 向量,最后存入数据库中,其中切割生成的 docs 表包含以下字段:

字段

类型

说明

id

serial

编号。

chunk

varchar(1024)

文章切块后的文本块。

intime

timestamp

文章的入库时间。

url

varchar(1024)

文本块所属文章的链接。

embedding

vecf16(512)

文本块 Embedding 向量。

  1. 创建存储向量的数据表。

CREATE TABLE docs (
    id SERIAL PRIMARY KEY,
    chunk VARCHAR(1024),
    intime TIMESTAMP,
    url VARCHAR(1024),
    embedding VECF16(512)
) DISTRIBUTED BY (id);
  1. 将向量列的存储模式设置为PLAIN,以降低数据行扫描成本,获得更好的性能。

ALTER TABLE docs ALTER COLUMN embedding SET STORAGE PLAIN;
  1. 对向量列建立向量索引。

-- 创建欧氏距离度量的向量索引。
CREATE INDEX idx_docs_feature_l2 ON docs USING vectors(embedding vecf16_l2_ops)
WITH (options = $$
optimizing.optimizing_threads = 3
segment.max_growing_segment_size = 100000
segment.max_sealed_segment_size = 8000000
[indexing.hnsw]
m=30
ef_construction=500
$$);  
  1. 为常用的结构化列建立索引,提升融合查询速度。

CREATE INDEX ON chunks(intime);

相关参考

支持的运算符类型

名称

描述

公式定义

<->

平方欧氏距离

<#>

负点积

<=>

余弦距离

向量运算符的使用示例:

-- 平方欧氏距离
SELECT '[1, 2, 3]'::vector <-> '[3, 2, 1]'::vector;

-- 负点积
SELECT '[1, 2, 3]'::vector <#> '[3, 2, 1]'::vector;

-- 余弦距离
SELECT '[1, 2, 3]'::vector <=> '[3, 2, 1]'::vector;

向量数据导入

向量的数据导入和普通的堆表数据导入相同,可以采用 INSERT 语法,也可以采用 COPY 语法。

本文以 INSERT 语法为例进行介绍。

-- 向量列采用字符串的方式表示,其格式为浮点型 JSON 数组
INSERT INTO docs VALUES (default, 'xxx', '2023-05-04', 'aaa.bbb.ccc/xxx.pdf', 
'[0.1, 0.2, 0.1, 0.3, ... 0.9]');

向量检索

对于向量列的搜索会使用到 HNSW 索引,此方式搜索速度较快,但得到的结果是一个近似的结果,一般召回率都可以达到 95% 以上。

语法

如下以欧氏距离为例:

SELECT ID, <vector_column_name> <-> '[0.1,0.2,0.3...]' as distance FROM <table_name> ORDER BY <order_column_name> <-> '[0.1,0.2,0.3...]' LIMIT <top_k>;

使用说明

  • 如果没有建立索引,上述近似的索引检索将退化为精确检索,该检索方式速度较慢,但准确率为 100%。

  • 在使用向量索引时,ORDER BY 语句必须包含 <-><#><=> 等操作符,否则不能有效使用向量索引的加速能力。同时, <-><#><=> 等操作符必须有对应距离度量的向量索引存在,否则也不能使用向量索引的加速能力。支持的操作符及其用法,请参见本文 “向量索引”部分。

示例

以 向量索引 中的知识库为例,如果我们要通过文本搜索它的来源文章,那么我们就可以直接通过向量索引检索进行查找。

具体 SQL 如下:

SELECT id, chunk, intime, url, embedding <-> '[10,2.0,..., 1536.0]' as distance FROM docs
ORDER BY
    embedding <-> '[10,2.0,..., 1536.0]'
LIMIT 100;

纯净模式常规模式

纯净模式

点击可全屏预览文档内容

鼠标选中内容,快速反馈问题

如果在文档使用中出现问题,可选中有问题的部分进行快速反馈,我们将跟进处理。
不再提示
好的,我知道了

聆听反馈