Vector Index 是 MaxCompute 提供的一种高效索引机制,用于加速大规模向量数据的相似性查询。本文介绍Vector Index 的使用说明及示例。
注意事项
创建VECTOR INDEX前请执行
SETPROJECT odps.schema.evolution.enable=true;命令,设置允许表结构变更(Schema Evolution)。目前只支持Delta Table概述创建Vector Index。
索引构建触发时机说明
同步生成:主要在离线批处理场景,通过
CREATE VECTOR INDEX定义索引后,SQL Insert操作同步触发索引生成。全量生成:当索引检索不够高效时,可以全量数据重建索引,可以通过
REBUILD INDEX命令触发,或者后台智能检测检索效率自动触发。
若待删除的列被Vector Index引用,系统将阻止该列的删除操作。需先删除对应的索引后再执行删除列操作。
对分区表重建 Vector Index 时,必须通过
PARTITION (...)明确指定分区范围,否则会抛出语义分析异常。分区表可以删除指定分区的index。
同一列仅允许创建一次索引,不支持重复创建。
同一张表中,多个向量列可分别创建不同名称的索引。
生成 VECTOR INDEX
创建VECTOR INDEX
为向量列创建索引,加速检索查询。创建命令如下:
CREATE VECTOR INDEX <index_name>
ON <table_name> (<description_embedding>)
IDXPROPERTIES (
'algorithm' = 'xxx',
'distance_type' = 'xxx',
'build_params' = 'xxx'
...
);参数说明:
参数 | 描述 |
index_name | 指定的索引名称。 |
table_name | 指定需要构建向量索引的表名称。当前仅支持 Delta Table概述 类型的表 |
description_embedding | 指定表中包含向量数据的列名,用于构建向量索引。 |
algorithm | 指定向量索引使用的构建算法。当前支持的算法为 |
distance_type | 指定向量之间的相似性计算方式。支持以下类型:
|
build_params | 索引构建时的参数配置,以 JSON 格式传入(如:'{"max_degree": 16, "ef_construction": 128}'),用于控制索引的构建质量和性能。常用参数包括:
Vector Index同时支持在索引内部对向量进行量化,量化相关参数如下:
关于量化配置相关实践说明请参考VECTOR INDEX 开启量化配置。 |
VECTOR INDEX 开启量化配置
VECTOR INDEX 支持在索引内部对向量进行量化,以减少索引存储和运行时内存,并降低检索过程中的内存访问开销。量化只改变索引内部的向量编码,不改变表中原始的VECTOR(FLOAT, dimension)数据,也不改变VECTOR_SEARCH的调用方式。MaxCompute VECTOR INDEX 支持以下两种检索方式:
单阶段检索:直接使用base_quantization_type完成图遍历和距离计算。索引结构简单,内存占用较低。
两阶段检索:先使用低精度base向量快速召回候选,再使用precise向量重新计算距离,在检索性能和召回率之间取得平衡。
常用量化参数组合如下:
配置 | 参数组合 | 参数配置说明 |
FP32 | base_quantization_type=fp32 | 特点:全精度基线,召回稳定,但内存占用较高 适用场景:对精度要求较高或数据规模较小的场景 |
FP16 | base_quantization_type=fp16 | 特点:向量部分内存约为FP32的50%,召回基本一致 适用场景:对精度要求较高或数据规模较小的场景,相比FP32, 有一定的召回损失 |
SQ8 | base_quantization_type=sq8 | 特点:向量部分内存约为FP32的25%,可能产生少量召回损失 适用场景:内存敏感且允许一定召回损失的场景 |
SQ8+高精度重排 | sq8+fp16或fp32 reorder | 特点:使用SQ8进行图遍历,再通过高精度距离计算恢复召回 适用场景:需要兼顾检索效率和召回率的场景 |
RaBitQ+高精度重排 | rabitq+fp16或fp32 reorder | 特点:使用更紧凑的编码进行图遍历,候选结果使用高精度向量重排 适用场景:索引重建较频繁且要求高召回的场景 |
量化主要带来以下收益:
减少索引文件大小和运行时内存占用。
降低索引加载和检索过程中的内存带宽开销。
提升CPU Cache利用率,使单个Worker能够加载和处理更多向量。
通过base量化和高精度reorder组合,在检索性能、资源成本和召回率之间灵活取舍。
推荐使用FP16创建HGraph索引,更多量化配置示例请参考示例:创建Vector Index,使用FP16量化、示例:创建Vector Index,使用RaBitQ低精度图遍历和高精度重排。
聚合VECTOR INDEX
INSERT OVERWRITE TABLE <table_name> [PARTITION <partition_spec>]
SELECT ......重建VECTOR INDEX
使用如下命令对存量数据重新生成VECTOR INDEX。
非分区表重建。
ALTER TABLE <table_name> REBUILD INDEX <index_name> ;分区表重建。 支持一次同时对多个分区的VECTOR INDEX进行REBUILD操作。
ALTER TABLE <table_name> PARTITION
(<partition_name1=value1>[, partition_name2=value2, ...]) REBUILD INDEX <index_name> ;
ALTER TABLE <table_name> PARTITION(partition_name >=value) REBUILD INDEX <index_name> ;列出表的VECTOR INDEX
SHOW INDEXES ON <table_name>;查看VECTOR INDEX的信息
DESC INDEX index_name ON <table_name> [PARTITION <partition_spec>];删除VECTOR INDEX
DROP INDEX [IF EXISTS] index_name ON <table_name> [PARTITION <partition_spec>];使用示例
数据准备
SET odps.sql.type.system.odps2=true;
SET odps.sql.type.vector.enable=true;
DROP TABLE IF EXISTS vector_test;
DROP VIEW IF EXISTS vector_test;
CREATE TABLE IF NOT EXISTS vector_test(
c0 int,
c1 vector(float, 2),
c2 vector(float, 3)
) STORED AS aliorc
TBLPROPERTIES (
'table.format.version'='2',
'acid.data.retain.hours'='24',
'columnar.nested.type'='true',
'transactional'='true'
);
INSERT OVERWRITE vector_test SELECT 1, vector(1.1F,2.2F), vector(1.1F,2.2F,3.3F) UNION ALL
SELECT 2, vector(2.2F,3.3F), vector(2.2F,3.3F,4.4F)
UNION ALL
SELECT 3, vector(3.3F,4.4F), vector(3.3F,4.4F,5.5F);示例:创建VECTOR INDEX,并插入数据
CREATE VECTOR INDEX c2_vector_index
ON vector_test (c2)
IDXPROPERTIES (
'algorithm' = 'hgraph',
'distance_type' = 'cosine',
'build_params' = '{"max_degree": 16, "ef_construction": 128}');
ALTER TABLE vector_test REBUILD INDEX c2_vector_index;
INSERT OVERWRITE vector_test SELECT 1, vector(1.1F,2.2F), vector(1.1F,2.2F,3.3F)
UNION ALL
SELECT 2, vector(2.2F,3.3F), vector(2.2F,3.3F,4.4F)
UNION ALL
SELECT 3, vector(3.3F,4.4F), vector(3.3F,4.4F,5.5F)
UNION ALL
SELECT 4, vector(4.4F,5.5F), vector(4.4F,5.5F,6.6F)
UNION ALL
SELECT 5, vector(5.5F,6.6F), vector(5.5F,6.6F,7.7F);
示例:VECTOR INDEX重建
ALTER TABLE vector_test REBUILD INDEX c2_vector_index;
SELECT * FROM vector_test;
-- 返回结果
+------+------+------+
| c0 | c1 | c2 |
+------+------+------+
| 1 | [1.1, 2.2] | [1.1, 2.2, 3.3] |
| 2 | [2.2, 3.3] | [2.2, 3.3, 4.4] |
| 3 | [3.3, 4.4] | [3.3, 4.4, 5.5] |
| 4 | [4.4, 5.5] | [4.4, 5.5, 6.6] |
| 5 | [5.5, 6.6] | [5.5, 6.6, 7.7] |
+------+------+------+
示例:列出表的VECTOR INDEX
SHOW INDEXES ON vector_test;
-- 返回结果
{"Indexes": [{
"createTime": 1779900024105,
"id": "512d520**45e1c7ba8",
"indexColumns": [{"name": "c2"}],
"name": "c2_vector_index",
"properties": {
"algorithm": "hgraph",
"build_params": "{\"max_degree\": 16, \"ef_construction\": 128}",
"distance_type": "cosine"},
"type": "VECTOR"}]}示例:查看VECTOR INDEX的信息
DESC INDEX c2_vector_index ON vector_test;
-- 返回结果
+------------------------------------------------------------------------------------+
| Index Detail |
+------------------------------------------------------------------------------------+
| name: c2_vector_index |
| id: 512d520**e1c7ba8 |
| index_type: VECTOR |
| index_columns: c2 |
| status: ACTIVE |
| coverage_percentage: 100% |
| storage_size_bytes: 6940 |
| properties: build_params={"max_degree": 16, "ef_construction": 128}, distance_type=cosine, algorithm=hgraph |
+------------------------------------------------------------------------------------+
示例:删除VECTOR INDEX
DROP INDEX c2_vector_index ON vector_test;
-- 返回结果
{"Indexes": []}示例:创建Vector Index,使用FP16量化
CREATE VECTOR INDEX doc_vector_index
ON doc_table (embedding)
IDXPROPERTIES (
'algorithm' = 'hgraph',
'distance_type' = 'dot_product',
'build_params' = '{
"max_degree":48,
"ef_construction":400,
"base_quantization_type":"fp16"
}'
);
-- 创建索引后,需要对存量数据执行索引重建
ALTER TABLE doc_table PARTITION (pt='20260730') REBUILD INDEX doc_vector_index;示例:创建Vector Index,使用RaBitQ低精度图遍历和高精度重排
CREATE VECTOR INDEX doc_vector_index
ON doc_table (embedding)
IDXPROPERTIES (
'algorithm' = 'hgraph',
'distance_type' = 'dot_product',
'build_params' ='{
"max_degree":48,
"ef_construction":400,
"base_quantization_type":"rabitq",
"use_reorder":true,
"precise_quantization_type":"fp32"
}'
);