StarRocks作为主流的MPP OLAP引擎,在AIGC日益火热的当下,我们也可以在OLAP基础上叠加AI能力,同时做结构化分析、语义搜索两大类事情,大大提高数据利用效率,扩展数据使用场景。

半结构化类型

向量是用半结构化类型表示的。

ARRAY

数组(Array) 是数据库中的一种扩展数据类型,其相关特性在众多数据库系统中均有支持,可以广泛的应用于 A/B Test 对比、用户标签分析、人群画像等场景。StarRocks 当前支持多维数组嵌套、数组切片、比较、过滤等特性。

create table t0(
  c0 INT,
  c1 ARRAY<INT>
)
duplicate key(c0)
distributed by hash(c0);

INSERT INTO t0 VALUES(1, [1,2,3]);

JSON

JSON 是一种轻量级的数据交换格式,JSON 类型的数据是一种半结构化的数据,支持树形结构。JSON 数据层次清晰,结构灵活易于阅读和处理,广泛应用于数据存储和分析场景

CREATE TABLE `tj` (
    `id` INT(11) NOT NULL COMMENT "",
    `j`  JSON NULL COMMENT ""
) ENGINE=OLAP
DUPLICATE KEY(`id`)
DISTRIBUTED BY HASH(`id`);

INSERT INTO tj (id, j) VALUES (1, parse_json('{"a": 1, "b": true}'));

MAP

MAP 是一种复杂数据类型,用于存储无序的键值对 (key-value pair),例如 {a:1, b:2, c:3}。Map 中的 Key 不能重复。一个 Map 最多支持 14 层嵌套

CREATE TABLE t0(
  c0 INT,
  c1 MAP<INT,INT>
)
DUPLICATE KEY(c0);

INSERT INTO t0 VALUES(1, map{1:2,3:NULL});

STRUCT

可以存储不同数据类型的元素

CREATE TABLE t0(
  c0 INT,
  c1 STRUCT<a INT, b STRING>
)
DUPLICATE KEY(c0);

INSERT INTO t0 VALUES(1, row(1, 'x'));

向量索引

StarRocks支持在Segment文件级别进行向量索引。索引将每个搜索项映射到Segment文件中的行ID,通过直接定位相应的数据行实现快速数据检索,而无需进行暴力的向量距离计算。系统目前提供两种类型的向量索引:倒排文件与乘积量化(IVFPQ)和分层可导航小世界(HNSW),每种都有其独特的组织结构

仅在v3.4或更高版本的存算一体集群中支持,且仍被社区标记为Beta功能

关于 Beta 功能的使用建议

索引类型

IVFPQ

倒排文件与乘积量化(IVFPQ)是一种用于大规模高维向量近似最近邻搜索的方法,常用于深度学习和机器学习中的向量检索任务。IVFPQ由两个主要组件组成:倒排文件和乘积量化。

  • 倒排文件:这是一个索引方法。它将数据集划分为多个簇(或Voronoi单元),每个簇都有一个质心(种子点),并将每个数据点(向量)分配到其最近的簇中心。对于向量搜索,IVFPQ只需搜索最近的簇,大大减少了搜索范围和复杂性。

  • 乘积量化:这是一种数据压缩技术。它将高维向量分割为子向量,并将每个子向量量化以映射到预定义集合中的最近点,从而在保持高精度的同时降低存储和计算成本。

HNSW

分层可导航小世界(HNSW)构建了一个分层图结构,其中每一层都是一个可导航的小世界(NSW)图。在图中,每个顶点代表一个数据点,边表示顶点之间的相似性。图的高层包含较少的顶点和稀疏的连接用于快速全局搜索,而低层包含所有顶点和密集的连接用于精确的局部搜索。

对于向量搜索,HNSW首先在顶层进行搜索,快速识别一个近似的最近邻区域,然后逐层向下移动,在底层找到精确的最近邻。

IVFPQ与HNSW的比较

  • 数据压缩比:IVFPQ具有较高的压缩比(约为1:0.15)。由于PQ会压缩向量,索引计算仅提供粗略排序后的初步排序结果,需要额外的精细排序以获得最终排序结果,导致更高的计算和延迟。HNSW具有较低的压缩比(约为1:0.8),无需额外处理即可提供精确排序,计算成本和延迟较低,但存储成本较高。
  • 召回率调整:两种索引都支持通过参数调整召回率,但在相似的召回率下,IVFPQ的计算成本更高。
  • 缓存策略:IVFPQ允许通过调整索引块的缓存比例来平衡内存成本和计算延迟,而HNSW目前仅支持全文件缓存。

启用

ADMIN SET FRONTEND CONFIG ("enable_experimental_vector" = "true");

创建

每个表仅支持一个向量索引。

索引构建参数

index_type
  • 默认值: N/A
  • 必需: 是
  • 描述: 向量索引类型。有效值:hnsw 和 ivfpq
dim
  • 默认值: N/A
  • 必需: 是
  • 描述: 索引的维度。索引构建完成后,不符合维度要求的向量将被拒绝加载到基础列中。必须是大于或等于1的整数。
metric_type
  • 默认值: N/A
  • 必需: 是
  • 描述: 向量索引的度量类型(测量函数)。有效值:
    • l2_distance: 欧氏距离。值越小,相似度越高。
    • cosine_similarity: 余弦相似度。值越大,相似度越高。
is_vector_normed
  • 默认值: false
  • 必需: 否
  • 描述: 向量是否已归一化。有效值为truefalse。仅当metric_typecosine_similarity时生效。如果向量已归一化,计算出的距离值将在[-1, 1]之间。向量必须满足平方和为1,否则返回错误。
M
  • 默认值: 16
  • 必需: 否
  • 描述: HNSW特定参数。图构建过程中为每个新元素创建的双向连接数。必须是大于或等于2的整数。M的值直接影响图构建和搜索的效率和准确性。在图构建过程中,每个顶点将尝试与其最近的M个顶点建立连接。如果一个顶点已经有M个连接,但发现了一个更近的顶点,最远的连接将被删除,并与更近的顶点建立新连接。向量搜索将从一个入口点开始,并沿着与其连接的顶点找到最近的邻居。因此,M的值越大,每个顶点的搜索范围越大,搜索效率越高,但图构建和存储的成本也越高。
efconstruction
  • 默认值: 40
  • 必需: 否
  • 描述: HNSW特定参数。包含最近邻居的候选列表的大小。必须是大于或等于1的整数。用于控制图构建过程中的搜索深度。具体来说,efconstruction定义了图构建过程中每个顶点的搜索列表(也称为候选列表)的大小。这个候选列表用于存储当前顶点的邻居候选者,列表的大小为efconstructionefconstruction的值越大,在图构建过程中被视为顶点邻居的候选者越多,因此图的质量(如更好的连通性)越好,但图构建的时间消耗和计算复杂度也越高。
nbits
  • 默认值: 16
  • 必需: 否
  • 描述: IVFPQ特定参数。乘积量化(PQ)的精度。必须是8的倍数。在IVFPQ中,每个向量被分割为多个子向量,然后每个子向量被量化。Nbits定义了量化的精度,即每个子向量被量化为多少个二进制位。nbits的值越大,量化精度越高,但存储和计算成本也越高。
nlist
  • 默认值: 16
  • 必需: 否
  • 描述: IVFPQ特定参数。簇的数量或倒排列表。必须是大于或等于1的整数。在IVFPQ中,数据集被划分为簇,每个簇的质心对应一个倒排列表。向量搜索将首先找到与数据点最近的簇质心,然后在相应的倒排列表中检索最近邻居。因此,nlist的值将影响搜索的准确性和效率。nlist的值越大,聚类的粒度越细,因此搜索的准确性越高,但搜索的复杂性也越高。
M_IVFPQ
  • 必需: 是
  • 描述: IVFPQ特定参数。原始向量将被分割成的子向量数量。IVFPQ索引将一个dim维向量分割成M_IVFPQ个等长的子向量。因此,它必须是dim值的因数。
CREATE TABLE hnsw (
    id     BIGINT(20)   NOT NULL COMMENT "",
    vector ARRAY<FLOAT> NOT NULL COMMENT "",
    INDEX hnsw_vector (vector) USING VECTOR (
        "index_type" = "hnsw", 
        "dim"="5", 
        "metric_type" = "l2_distance", 
        "is_vector_normed" = "false", 
        "M" = "16", 
        "efconstruction" = "40"
    )
) ENGINE=OLAP

CREATE TABLE ivfpq (
    id     BIGINT(20)   NOT NULL COMMENT "",
    vector ARRAY<FLOAT> NOT NULL COMMENT "",
    INDEX ivfpq_vector (vector) USING VECTOR (
        "index_type" = "ivfpq", 
        "dim"="5", 
        "metric_type" = "l2_distance", 
        "is_vector_normed" = "false", 
        "nbits" = "16", 
        "nlist" = "40"
    )
) ENGINE=OLAP

搜索

cosine_similarity(a, b) 计算两个向量的余弦夹角来评估向量之间的相似度

approx_l2_distance(a, b) 计算两个向量的L2距离(欧几里得距离)

INSERT INTO hnsw VALUES (1, [1,2,3,4,5]), (2, [4,5,6,7,8]);

SELECT id, approx_l2_distance([1,1,1,1,1], vector) 
FROM hnsw 
ORDER BY approx_l2_distance([1,1,1,1,1], vector) 
LIMIT 1;

为搜索微调索引参数

参数调优在向量搜索中至关重要,因为它影响性能和准确性。建议在小数据集上调优搜索参数,并在达到预期的召回率和延迟后再转向大数据集。

搜索参数通过SQL语句中的提示传递。

对于HNSW索引

在继续之前,请确保向量列已使用HNSW索引构建。

SELECT 
    /*+ SET_VAR (ann_params='{efsearch=256}') */ 
    id, approx_l2_distance([1,1,1,1,1], vector) 
FROM test_hnsw 
WHERE id = 1 
ORDER BY approx_l2_distance([1,1,1,1,1], vector) 
LIMIT 1;

参数

efsearch
  • 默认值: 16
  • 必需: 否
  • 描述: 控制精度-速度权衡的参数。在分层图结构搜索中,此参数控制搜索期间候选列表的大小。efsearch的值越大,准确性越高,但速度越慢。

对于IVFPQ索引

在继续之前,请确保向量列已使用IVFPQ索引构建。

SELECT 
    /*+ SET_VAR (ann_params='{nprobe=256,max_codes=0,scan_table_threshold=0,polysemous_ht=0,range_search_confidence=0.1}') */ 
    id, approx_l2_distance([1,1,1,1,1], vector) 
FROM test_ivfpq 
ORDER BY approx_l2_distance([1,1,1,1,1], vector) 
LIMIT 1;

参数

nprobe
  • 默认值: 1
  • 必需: 否
  • 描述: 搜索期间检查的倒排列表数量。nprobe的值越大,准确性越高,但速度越慢。
max_codes
  • 默认值: 0
  • 必需: 否
  • 描述: 每个倒排列表检查的最大代码数。此参数也会影响准确性和速度。
scan_table_threshold
  • 默认值: 0
  • 必需: 否
  • 描述: 控制多义哈希的参数。当元素的哈希与要搜索的向量的哈希之间的汉明距离低于此阈值时,该元素将被添加到候选列表中。
polysemous_ht
  • 默认值: 0
  • 必需: 否
  • 描述: 控制多义哈希的参数。当元素的哈希与要搜索的向量的哈希之间的汉明距离低于此阈值时,该元素将直接添加到结果中。
range_search_confidence
  • 默认值: 0.1
  • 必需: 否
  • 描述: 近似范围搜索的置信度。值范围:[0, 1]。将其设置为1可产生最准确的结果。

最佳实践

外部存储 + StarRocks 索引/元数据

外部存储非结构化数据

将非结构化数据存储在专门的对象存储或文件系统中,这些系统更擅长处理大文件和非结构化数据:

  • 对象存储(推荐) :如 AWS S3、阿里云 OSS、腾讯云 COS 等。

  • 分布式文件系统 :如 HDFS。

StarRocks 存储元数据和索引

在 StarRocks 中创建一个表,用于存储非结构化数据的 元数据索引信息

字段名 数据类型 描述
doc_id VARCHAR 文档的唯一 ID。
s3_path VARCHAR 文档在 S3/OSS 上的完整路径(核心)。
file_size BIGINT 文件大小。
upload_time DATETIME 上传时间。
tags ARRAY<VARCHAR> 文档的标签或分类(用于过滤)。
summary VARCHAR 文档的摘要或关键信息。
vector_embedding ARRAY<FLOAT> (关键) 文档内容的向量嵌入(用于向量搜索)。

核心应用场景:向量搜索(Vector Search)

  1. 提取内容 :使用 NLP 工具(如 LangChain)从文档中提取文本内容。LangChain已提供SR支持 链接

  2. 生成向量 :使用预训练的 Embedding 模型(如 OpenAI, BGE, E5 等)将文本内容转换为高维浮点数向量。

  3. 存储向量 :将生成的向量存储在 StarRocks 表的 ARRAY<FLOAT> 字段中。

  4. 查询 :使用 StarRocks 的 向量函数 (如 l2_distance , cosine_similarity )结合 索引 (如 IVFPQHNSW )进行高效的近似最近邻(ANN)搜索。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐