Chapter 2 Milvus核心概念:数据模型与索引体系 2.1 学习目标 掌握Milvus的核心数据模型(数据库、集合、分区、字段、向量、数据行)及各组件的详细特性与约束规则 理解数据模型各层级的嵌套关系、依赖逻辑及多租户隔离机制 掌握Milvus索引的核心作用、底层原理与常见索引类型的技术特性 学会根据数据规模、精度需求、资源限制选择合适的索引类型与距离度量方式 2.2 Milvus核心数据模型 Milvus采用“多层级嵌套”的数据组织模型,从顶层到底层依次为:数据库(Database)→ 集合(Collection)→ 分区(Partition)→ 段(Segment)→ 字段(Field)→ 数据行(Row)。
Milvus采用“多层级嵌套”的数据组织模型,从顶层到底层依次为:数据库(Database)→ 集合(Collection)→ 分区(Partition)→ 段(Segment)→ 字段(Field)→ 数据行(Row)。该模型通过清晰的层级划分实现数据的逻辑隔离、精细化管理与高效检索,各层级的核心定义、功能特性及关联关系如下:
数据库是Milvus中最高层级的逻辑命名空间,核心作用是实现不同业务场景、多租户的数据隔离与资源管控。它为下层的集合(Collection)提供独立的存储与操作边界,不同数据库内的资源(集合、索引等)互不干扰,支持多业务线在同一Milvus实例中并行运行。
核心特性与约束:
集合是Milvus中存储向量数据及关联元数据的基本单元,等价于传统关系型数据库中的“表”,但专为高维向量数据的存储与检索优化设计。每个集合必须通过Schema(模式)定义数据结构,所有插入的数据需严格遵循Schema规范,确保数据类型与字段约束的一致性。Schema支持动态特性,可在特定场景下提升集合的扩展性
核心特性与约束:
Schema依赖:必须显式定义Schema(数据模式),Schema是集合数据结构的“蓝图”,核心组成包括字段定义、字段约束、系统默认配置三大模块,是数据校验、存储优化与检索效率保障的基础。其中字段定义需明确字段名称、数据类型;字段约束包含是否为主键、是否非空、默认值、长度限制等;系统默认配置涵盖时间戳字段、动态字段开关等。Schema定义后需严格遵循,所有插入数据将通过Schema进行类型校验与约束检查,不满足条件的数据会被拒绝插入
分区是集合的逻辑子单元,用于对集合内的数据按指定规则进行分组管理,本质是将一个集合的Schema复用至多个子数据集。通过分区可缩小检索时的数据扫描范围,提升查询效率,同时简化数据生命周期管理(如按分区清理过期数据)。
核心特性与约束:
字段是数据存储的最小单元,定义了数据的类型、属性约束及存储特性,所有字段均需在集合的Schema中预先定义(动态字段除外)。根据存储数据类型的不同,分为向量字段与标量字段两类,两类字段协同实现“向量检索+标量过滤”的混合检索能力。此外,Milvus还包含系统默认字段,同时支持字段级索引配置,进一步提升检索效率
专门用于存储高维向量数据(如文本嵌入向量、图像特征向量),是Milvus实现相似性检索的核心字段。
用于存储与向量关联的属性元数据,支持多种基础数据类型,可作为检索时的过滤条件(如价格≤1000、是否上架)。
数据行是集合中实际存储的单条数据记录,对应Schema定义的一套完整字段值组合,即“主键值+向量值+其他标量值”的集合。每条数据行会通过分区规则分配至集合的某个分区,最终存储在对应分区的段(Segment)中。
示例:一条商品向量数据行
{ "商品ID(主键)": 1001, "商品名称(String)": "华为手机", "价格(Float64)": 3999.0, "是否上架(Bool)": true, "向量(FLOAT_VECTOR)": [0.12, 0.34, ..., 0.56](768维) }
核心特性:数据行的字段值必须匹配Schema定义的类型与约束;支持动态插入,但未启用动态字段时不允许新增Schema外的字段;删除数据行时需通过主键或分区批量删除。此外,Milvus默认会为每个数据行添加两个系统字段,无需在Schema中定义:① _row_id:系统生成的唯一行标识,用于内部数据定位;② _timestamp:数据插入时的时间戳,用于数据版本管理与时间范围过滤
Database(业务/租户隔离)→ Collection(Schema定义的数据集)→ Partition(数据集分组)→ Segment(物理存储单元)→ Field(数据最小单元)→ Row(单条数据记录)
核心关联逻辑:一个Database包含多个Collection,一个Collection包含多个Partition,一个Partition包含多个Segment,一个Segment包含多个Row,每个Row包含所有Field的具体值。
| Milvus数据模型 | 传统关系型数据库(如MySQL) | 核心差异 |
|---|---|---|
| Database | Database | 均为顶层命名空间,支持多租户隔离;Milvus新增资源组绑定能力 |
| Collection | Table | 均为数据存储基本单元;Collection强制要求向量字段,依赖Schema定义 |
| Partition | Partition | 均为表/集合的子单元;Milvus支持Partition Key自动路由,隔离粒度更细 |
| Field(向量+标量) | Column | Milvus新增向量字段类型,支持高维数据存储;主键字段为强制要求 |
| Row | Row/Tuple | 均为单条数据记录;Milvus行必须包含向量值,支持混合检索 |
索引是提升Milvus相似性检索性能的核心技术手段。未创建索引时,Milvus采用“暴力检索(Brute-force Search)”,需遍历所有向量计算距离,效率极低(亿级数据检索耗时分钟级);创建索引后,通过预构建的索引结构缩小检索范围,可将亿级向量检索耗时缩短至毫秒级,实现高效相似性匹配。
想象一下,你来到一个拥有百万册书籍的超大型图书馆,想要找到与《三体》最相似的10本书。如果没有目录索引系统,你需要怎么做?唯一的办法就是从第一个书架开始,逐本翻阅每一本书,比较它们与《三体》的相似度。这就是所谓的"全表扫描"或"暴力搜索"。
这种方法的致命缺陷在于它的线性增长特性。当图书馆只有1万册书时,你可能只需要几个小时就能完成搜索。但当藏书量增加到100万册时,搜索时间就会相应增加100倍。在计算机领域,我们称之为O(n)时间复杂度——数据量增长多少倍,处理时间就增长多少倍。
在实际的向量数据库应用中,这种暴力搜索方式会带来严重的性能问题。每个向量比较都需要进行数十次甚至数百次数学运算,当数据量达到百万级别时,总计算量将变得极其庞大,响应时间可能长达数秒甚至分钟级,完全无法满足实时查询的需求。
既然精确搜索的成本如此高昂,人们开始思考:我们是否真的需要百分之百精确的结果?在许多实际应用场景中,答案是否定的。
以视频网站推荐系统为例,当我们为用户推荐可能喜欢的视频时,并不需要找到"绝对最相似"的十个视频,而是需要找到"足够相似"且多样化的推荐内容。即使偶尔有一两个推荐结果不是最优解,用户通常也不会察觉,但推荐速度的提升却是明显可感知的。
这种思路催生了近似最近邻搜索技术。其核心思想是通过某种预处理方式,将数据组织成更容易搜索的结构。继续用图书馆的比喻:我们不再需要逐本翻阅所有书籍,而是先查看分类标签,只检索"科幻小说"区域内的书籍,或者通过作者索引直接找到刘慈欣的其他作品。
这种方法的巧妙之处在于它接受了一定程度的不完美,却换来了效率的质的飞跃。从需要检查百万本书籍,到只需要检查几千本,搜索速度可能提升数百倍,而精度损失可能只有百分之几。
向量索引解决了两个关键问题:
这就是ANNS(近似近邻检索)的核心理念:通过在可接受范围内牺牲一定精确度,换取检索效率的显著提升。
索引技术的本质是一种典型的"空间换时间"策略。就像图书馆需要额外空间来存放目录卡片和索引系统一样,向量索引也需要占用额外的存储空间。这种空间开销有时甚至可能超过原始数据本身的大小。
除了存储开销,索引还需要预处理时间。构建索引就像图书馆员需要花费时间整理图书分类、编写目录卡片一样,需要前期投入时间进行数据处理和组织。这个过程可能很耗时,特别是对于大规模数据集。
更重要的是精度与速度的权衡。不同的索引算法在这两者之间提供了不同的平衡点。有些索引追求极致的速度,愿意牺牲较多的精度;有些则偏向保守,以较小的速度提升换取更高的精度保证。
这种权衡没有绝对的最优解,完全取决于具体应用场景的需求。在医疗影像分析中,可能宁愿等待更长时间也要保证结果的绝对准确;而在实时商品推荐中,快速的近似结果可能比缓慢的精确结果更有价值。
理解这种权衡关系,是选择和优化索引方案的关键第一步。后续章节中介绍的各种索引类型,本质上都是在精度、速度、内存占用这三个维度上提供不同的配置选项。
总结一下:索引并非是万能,使用它需要付出以下代价
但相比收益(查询速度提升数十倍甚至数百倍),这些代价通常是值得的。
ANNS(近似近邻检索)的核心技术理念在于不局限于返回最精确的topK结果,而是通过在可接受范围内牺牲一定精确度,换取检索效率的显著提升。其核心价值体现在能够有效加快大型数据集上相似性搜索的速度,从而提升此类查询的实用性 。
作为实现ANNS的关键组件,索引是建立在数据之上的附加结构,其内部结构取决于所采用的具体ANNS算法。在向量数据库Milvus中,索引作为字段级结构存在,主要用于提升向量搜索和标量过滤性能。然而,索引的构建和使用并非无代价:它会产生额外的预处理时间、存储空间及RAM开销,同时可能导致召回率的轻微降低(尽管这种影响通常可忽略,但仍需关注)。因此,在实际应用中需权衡索引的预处理成本与搜索收益。
ANNS向量索引的分类可从多个维度构建,核心包括实现方法与向量嵌入类型两大逻辑维度,不同维度间存在交叉关联,共同构成索引技术的全局认知框架。
从实现方法角度,ANNS向量索引可分为四大类:基于树结构、基于图结构、基于哈希方法和基于量化技术。基于树结构的索引通过空间划分构建层级树(如KD树),实现向量的快速检索;基于图结构的索引通过构建近邻图(如HNSW),利用图遍历高效定位相似向量;基于哈希方法的索引将高维向量映射到低维哈希码,通过哈希表实现快速查找;基于量化技术的索引则通过向量编码压缩(如乘积量化PQ、标量量化SQ),在降低存储和计算成本的同时保持检索性能。
| 实现方法分类 | 核心技术原理 | 典型代表算法 |
|---|---|---|
| 基于树结构 | 空间划分构建层级树 | KD树 |
| 基于图结构 | 构建近邻图实现高效遍历 | HNSW |
| 基于哈希方法 | 高维向量映射到低维哈希码 | 局部敏感哈希(LSH) |
| 基于量化技术 | 向量编码压缩降低存储成本 | 乘积量化(PQ)、标量量化(SQ) |
从向量嵌入类型角度,索引可按处理的数据类型划分为浮点嵌入索引、二进制嵌入索引、稀疏嵌入索引及GPU索引。浮点嵌入索引支持各类浮点精度向量(如FLOAT32、FLOAT16),典型代表包括FLAT、IVF系列(IVF_FLAT、IVF_SQ8、IVF_PQ)、HNSW、SCANN、DiskANN等;二进制嵌入索引针对二值化向量,如BIN_FLAT、BIN_IVF_FLAT;稀疏嵌入索引适用于非零元素占比低的稀疏向量,如SPARSE_INVERTED_INDEX、SPARSE_WAND;GPU索引则通过图形处理器加速计算,如GPU_CAGRA、GPU_IVF_FLAT等。
| 嵌入类型 | 支持数据类型 | 典型索引示例 |
|---|---|---|
| 浮点嵌入索引 | FLOAT32、FLOAT16等精度向量 | FLAT、IVF系列、HNSW、SCANN、DiskANN |
| 二进制嵌入索引 | 二值化向量 | BIN_FLAT、BIN_IVF_FLAT |
| 稀疏嵌入索引 | 非零元素占比低的稀疏向量 | SPARSE_INVERTED_INDEX、SPARSE_WAND |
| GPU索引 | 各类向量(需GPU加速) | GPU_CAGRA、GPU_IVF_FLAT、GPU_IVF_PQ |
不同分类维度存在显著关联性。例如,基于量化技术的索引(如IVF_SQ8、IVF_PQ)主要属于浮点嵌入索引,通过量化压缩浮点向量以平衡性能与资源消耗;二进制嵌入索引的实现常结合量化或哈希方法,将浮点向量二值化后构建索引。以Milvus为例,其索引类型与目标字段数据类型严格映射:浮点向量字段支持IVF系列、HNSW等多种实现方法的索引;二进制向量字段对应BIN_FLAT等专用索引;稀疏浮点向量字段则适配稀疏反转索引,体现了向量嵌入类型与实现方法的协同选择逻辑。
Milvus 支持 11 种以上索引类型,可分为“近似最近邻检索(ANN)索引”和“精确最近邻检索(NN)索引”两大类。其中 ANN 索引通过牺牲少量精度来换取显著的检索效率提升,是实际大规模应用的主流选择;而 NN 索引则适用于小规模数据或对精度要求极高的场景。
FLAT索引代表了向量搜索中最直接了当的方法——暴力搜索。这种索引方式不对向量进行压缩,采用暴力搜索(即穷举搜索)策略,在每次查询时将目标向量与数据集中的所有向量进行逐一比较。这一特性使得FLAT能够保证100%的召回率,也是目前唯一能实现这一结果的索引类型。因此,FLAT索引在小规模数据集(通常为百万量级)或对检索精度有极高要求的场景中具有不可替代性,尤其适用于需要完美精确度的任务。
想象一下在一个巨大的图书馆里寻找特定书籍的场景。如果使用FLAT索引,就相当于不借助任何目录系统,从第一个书架开始,逐本检查每本书是否符合你的需求。这种方法虽然极其耗时,但却能保证你不会错过任何一本可能相关的书籍。
FLAT索引的核心价值在于它提供了绝对精确的结果。在某些对精度要求极高的场景中,这种保证是无可替代的。例如在医疗影像分析中,即使只有一个可疑病灶被漏检,都可能造成严重的临床后果。又如在法律文档检索中,任何相关判例的遗漏都可能影响案件的结果。
然而,这种精确性是以巨大的计算开销为代价的。当数据量增长时,FLAT索引的搜索时间呈线性增长,很快就会达到无法接受的程度。这就好比在一个拥有千万册藏书的图书馆中逐本翻阅——理论上可行,但实际上完全不现实。
FLAT索引最适合的是那些数据量不大但对精度要求极高的场景,不适合处理海量数据。一般来说,当向量数量在十万条以内时,FLAT索引还能提供相对可接受的性能。超过这个规模,就需要考虑其他更高效的索引方式了。在参数设置方面,FLAT索引较为简单,仅需指定距离计算方式(如L2欧氏距离或IP内积),且无需额外的训练过程。此外,FLAT索引的检索结果常被用作其他近似索引的性能比较基准,为评估不同索引的召回率提供参考标准。
总结一下上面的描述,可以总结为:FLAT索引是最简单直观的索引类型,它的工作原理就像在图书馆里一本一本地翻书:
| 特性 | 详细说明 |
|---|---|
| 索引类型 | 精确检索索引,采用暴力搜索(穷举搜索)策略 |
| 核心原理 | 不对向量进行压缩,每次查询时将目标向量与数据集中所有向量逐一比较 |
| 召回率 | 100%,是目前唯一能实现这一结果的索引类型 |
| 适用场景 | 小规模数据集(通常为百万量级)或对检索精度有极高要求的场景 |
| 搜索速度 | 较慢(由于线性扫描本质) |
| 海量数据适用性 | 不适合处理海量数据 |
| 参数设置 | 仅需指定距离计算方式(如L2欧氏距离或IP内积),无需额外训练过程 |
| 主要用途 | 精确检索任务、作为其他近似索引的性能比较基准 |
倒排索引如同图书馆的分类目录,它会将数据预先划分成多个类别,比如 "科技类""文学类" 等,在执行搜索任务时,只需在相关类别内进行数据比对,从而减少搜索范围。
倒排索引主要由词汇表和倒排记录表(Posting List, PL)组成,词汇表存储着在所有文档集合中出现过的词汇,倒排记录表记录包含对于每一个词汇项对应的所有文档标识符(即文档的ID)以及词频、位置等信息。
假设有以下文档集合:
文档1: "Hello world"
文档2: "Hello DataWhale"
文档3: "Hello easy_vectorDB"
>构建倒排索引后,结果如下: > Hello: [文档1, 文档2, 文档3] > world: [文档1] > DataWhale: [文档2] > easy_vectorDB: [文档3]
IVF系列索引的核心机制是通过基于中心点的分区策略将向量聚类到多个桶中,在搜索过程中仅扫描与查询向量中心点相近的桶内向量,从而显著降低计算成本。
上图中你可以看到IVF系列索引对数据的聚类,通过不同的聚类算法将数据聚类到不同的桶中,每一聚类都有一个聚类中心。
每一个聚类中心对应的有一个向量表示,如上图所示。
当我们提供一个查询向量时,会先计算该向量与所有聚类中心之间的距离,然后选择距离最近的聚类中心,并仅搜索该聚类中心内的向量。通过这种方式,IVF系列索引能够显著减少搜索空间,提高搜索效率。但这种方法也存在缺点,在进行近似最近邻搜索时,可能会出现一种情况:通过算法找到的"最接近查询嵌入的候选嵌入"实际上并不是真正的最近邻。
具体来说,当使用聚类方法(例如IVF_FLAT中的k-means)对数据点进行分组时,每个聚类都有一个中心点(centroid)。在查询时,算法首先会确定哪个聚类的中心点与查询向量最为接近,然后在该聚类内部查找最近的向量作为候选嵌入。然而,如果实际的最近邻(即距离查询向量最近的数据点)位于另一个聚类中,而这个聚类的中心点与查询向量的距离相对更远,那么根据中心点选择的聚类将不会包含真实的最近邻。这就导致了找到的候选嵌入不是准确的最近嵌入。
为了解决这个问题,IVF_FLAT提供了两个超参数供我们调整:
nlist:指定整个数据集将被分成多少个子集(即使用k-means算法创建的聚类中心的数量)。增加这个值可以使得每个分区内的向量更加相似,但同时也会增加计算开销。通常设为数据量的平方根,如100万数据可设为1000。nlist越大,每个聚类内向量越少,搜索越快,但聚类质量可能下降
nprobe:搜索期间会检查的分区数量。增大这个值可以提高召回率(即找到真正最近邻的可能性),因为更多的候选分区被考虑进来,但这同样会增加搜索时间。通常为nlist的1%-10%,如nlist=1024时,nprobe可设为8-100。nprobe越大,召回率越高,但搜索时间越长
通过增加nprobe 值,可以在搜索中包含更多分区,这有助于确保不会错过与查询最接近的嵌入,即使它位于不同的分区中。不过,这样做的代价是增加搜索时间,因为需要评估更多候选项。
IVF系列包含IVF_FLAT、IVF_SQ8和IVF_PQ三种主要类型,其技术演进逻辑围绕压缩率提升与精度平衡展开,逐步实现内存占用的降低。
| 索引类型 | 构建参数 | 搜索参数 | 压缩技术 | 内存占用 | 召回率 |
|---|---|---|---|---|---|
| IVF_FLAT | nlist(范围[1,65536],默认128) | nprobe(范围[1,nlist],默认8)、max_empty_result_buckets(范围[1,65535],默认2) | 无压缩 | 最高(与原始数据相近) | 最优 |
| IVF_SQ8 | nlist(范围[1,65536],默认128) | nprobe(范围[1,nlist],默认8)、max_empty_result_buckets(范围[1,65535],默认2) | 标量量化(SQ),将FLOAT(4字节)转换为UINT8(1字节) | 中等(减少70-75%内存消耗) | 次之 |
| IVF_PQ | nlist(范围[1,65536],默认128)、m(乘积量化因子数,需满足dim mod m=0)、nbits(范围[1,64],默认8) | nprobe(范围[1,nlist],默认8)、max_empty_result_buckets(范围[1,65535],默认2) | 乘积量化(PQ),将高维向量分解为低维子向量并量化 | 最低 | 最低 |
IVF_FLAT作为系列基础,是FLAT索引的改进版本,其核心特点是每个桶内存储原始向量,未进行压缩处理。构建时需指定nlist参数(聚类数量,取值范围[1,65536],默认128)以确定桶的数量;搜索阶段支持普通搜索(通过nprobe参数设置查询桶数,范围[1,nlist],默认8)和范围搜索(通过max_empty_result_buckets参数控制最大空白桶数,范围[1,65535],默认2)。由于保留原始向量,IVF_FLAT的索引文件大小与原始数据相近,内存占用最高,但召回率表现最优。
在IVF_FLAT基础上,IVF_SQ8通过引入标量量化(SQ)技术实现压缩,将每个4字节的FLOAT类型向量分量转换为1字节的UINT8类型,可减少70-75%的内存消耗(例如1B规模的SIFT数据集仅需140GB存储空间)。其构建参数(nlist)和搜索参数(nprobe、max_empty_result_buckets)与IVF_FLAT完全一致,适用于内存资源有限且可接受召回率轻微下降的场景。相较于IVF_FLAT,IVF_SQ8以精度的小幅损失换取了显著的内存优化。
IVF_PQ则进一步采用乘积量化(PQ)技术深化压缩,其流程为:先通过IVF进行聚类分区,再将每个高维向量分解为多个低维子向量,对各子向量独立量化后存储。该方法使索引文件体积较IVF_SQ8进一步减小,但精度损失更为明显。构建时除nlist参数外,还需配置m(乘积量化因子数,需满足向量维度dim能被m整除)和nbits(每个子向量的存储位数,范围[1,64],默认8)。搜索参数与IVF_FLAT、IVF_SQ8保持一致。
综合来看,IVF系列三种索引的内存占用呈现IVF_PQ < IVF_SQ8 < IVF_FLAT的关系,而召回率则相反,IVF_FLAT最优,IVF_SQ8次之,IVF_PQ最低。这种差异源于量化技术的逐步引入与深化,体现了存储效率与检索精度之间的权衡。
图索引像是一张关系网,每个数据点都记录着自己的 "最近邻居",搜索时能够沿着这张关系网快速跳转,实现高效查找。在前文中,我们使用过的HNSW索引就是一种典型的图索引。
HNSW索引是一种基于图的索引,在使用此索引构建向量后,能够提高搜索的精度(相对于使用量化的索引来说)和速度。但内存的消耗会增大。
分层导航小世界(HNSW)算法构建了一个多层图,有点像不同缩放级别的地图。底层包含所有数据点,而上层则由从底层采样的数据点子集组成。在这种层次结构中,每一层都包含代表数据点的节点,节点之间由表示其接近程度的边连接。上层提供远距离跳转,以快速接近目标,而下层则进行细粒度搜索,以获得最准确的结果。
下面是它的工作原理:
HNSW的性能可以通过几个关键参数进行精细调节。M参数控制每个节点的连接数量,就像决定每个人维持多少社会关系。ef参数则控制搜索时的探索范围,相当于决定在寻找目标时要问多少个朋友。
这些参数的设置需要仔细权衡。过多的连接会增加网络复杂度和内存占用,但能提高搜索精度和速度。过大的探索范围能提高找到最优结果的概率,但也会增加搜索时间。在实际应用中,通常需要根据具体的硬件资源和工作负载特征来找到最佳配置。
M(连接度数):
efConstruction(构建参数):
ef(搜索参数):

HNSW(Hierarchical Navigable Small World)通过构建多层导航图实现高效向量检索,其核心结构特点为上层稀疏、下层密集,搜索过程从上层起始逐步向下层精确导航,这一设计使其能够实现对数时间复杂度的查询性能,从而具备低延迟优势。HNSW在每层都是一个小世界图,通过图数据结构组织,上层节点也是通过投币决定在哪一层,并且它们在下层图中都有记录。
"投币"机制,是一种用于决定节点在图中所处层级的随机化策略。其原理类似于通过抛硬币(即概率决策)来确定新插入节点是否进入更高层图结构的过程。
- 新节点加入时,会先被放入最底层(第0层),然后以一定的概率(如50%)决定是否将其提升到上一层。这个过程可以形象地理解为"投币":如果结果是"正面",节点就进入上一层;如果是"反面",则停留在当前层。
- 通常情况下,高层级的节点数量比低层级少得多,例如每向上一层,节点数量大约减半。这种设计保证了图结构的稀疏性,使得高层可用于快速导航,而底层则提供更精细的搜索能力。
- 上层图可以看做下层图的一个缩影,检索时,从上到下,不断指引检索过程逐步靠近想要探寻的向量空间。另外在构图过程中HNSW通过边的裁剪来保证图的连通性。
在构建阶段,通过参数M(图中节点最大传出连接数量,取值范围[2,2048])控制图的连接密度,efConstruction(构建时的搜索范围,取值范围[1,int_max])平衡索引质量与构建时间;搜索阶段则通过参数ef(搜索时的搜索范围,取值范围[top_k,int_max])调节查询时间与准确度的权衡。
为优化内存占用,HNSW系列衍生出多种量化变体,这些变体通常通过牺牲部分召回率和构建速度来换取内存效率的提升。HNSW_SQ结合标量量化(SQ)技术,将浮点数据离散化为有限数值(如SQ6量化为64个值),显著减少内存占用,同时保持较高的QPS性能,但构建时间较基础HNSW有所增加。HNSW_PQ则采用乘积量化(PQ),将向量分解为多个子向量并分别量化,可灵活权衡索引大小与准确性,但相比HNSW_SQ,其QPS和召回率更低,构建时间更长。
| 变体名称 | 核心技术 | 内存占用 | QPS性能 | 构建时间 | 召回率 | 主要特点 |
|---|---|---|---|---|---|---|
| HNSW | 分层导航小世界图 | 高 | 高 | 基准 | 高 | 适用于高速查询、高召回率场景,通过M和ef参数控制性能 |
| HNSW_SQ | 标量量化(如SQ6) | 低 | 较高 | 适度增加 | 较高 | 将浮点数据离散化为有限数值(如64个值),显著减少内存占用 |
| HNSW_PQ | 乘积量化 | 中-低 | 中 | 更长 | 中 | 向量分解为子向量量化,可灵活权衡索引大小与准确性 |
| HNSW_PRQ | 乘积残差量化 | 中-低 | 中 | 增加数倍 | 与PQ相当 | 对PQ残差再次量化,压缩率控制更灵活,精度保持或提升 |
HNSW_PRQ作为基于乘积残差量化(PRQ)的变体,通过对PQ量化后的残差进行再次量化,进一步优化了索引大小与准确性的权衡灵活性。在相同压缩率下,HNSW_PRQ的QPS和召回率与HNSW_PQ相当,但其残差补偿机制使得在精度保持或提升的同时,能够实现更灵活的压缩控制,不过这也可能导致构建时间增加数倍。
| 特性 | HNSW | IVF系列 |
|---|---|---|
| 查询速度 | 通常更快(对数时间复杂度) | 较慢 |
| 内存占用 | 很高(需要存储图结构) | 中等到低 |
| 精度 | 高 | 取决于nprobe设置 |
| 构建时间 | 中等 | 较短 |
| 适用场景 | 低延迟、高精度需求 | 内存敏感、大规模数据 |
选择HNSW:
不选择HNSW:
在浮点嵌入索引中,SCANN与DiskANN作为两类重要的优化方案,分别在查询性能与大规模数据存储方面展现了独特优势。
SCANN(可扩展近邻)与IVF_PQ在基础架构上具有相似性,但通过引入SIMD(单指令多数据)优化显著提升了计算效率,尤其针对GPU环境进行了深度适配,从而实现了更高的查询吞吐量(QPS)。其核心优势在于极高速查询能力与高召回率,适用于内存资源充足的场景。在参数配置方面,SCANN的构建参数包括nlist(聚类数量)和with_raw_data(是否包含原始数据,默认值为True);搜索阶段则可通过调整nprobe(查询的聚类中心数量)、reorder_k(候选向量数量,默认值为top_k)及max_empty_result_buckets(范围搜索参数,默认值为2)进一步优化性能。
| 索引类型 | 核心技术 | 适用场景 | 构建参数 | 搜索参数 | |
|---|---|---|---|---|---|
| SCANN | 类IVF_PQ架构,SIMD优化,GPU适配 | 极高速查询、高召回率、内存资源充足场景 | nlist(聚类数量)、with_raw_data(默认True) | nprobe、reorder_k(默认top_k)、max_empty_result_buckets(默认2) | |
| DiskANN | Vamana图结构,PQ量化,磁盘存储 | 内存无法容纳的十亿级及以上大规模数据集 | - | - |
DiskANN则专注于解决内存资源限制下的大规模数据存储问题,其技术路径基于Vamana图结构,并结合乘积量化(PQ)技术实现磁盘-内存混合存储。具体而言,DiskANN将图结构存储于磁盘以突破内存容量限制,同时通过PQ对向量进行压缩,减小数据体积并加速近似距离计算,有效缓解了磁盘IOPS瓶颈。这一设计使其特别适用于内存无法容纳的十亿级及以上规模数据集,在平衡查询延迟与存储容量方面具有不可替代性。
二进制嵌入索引通过将向量转换为二进制表示形式,显著提升了存储效率。其存储空间计算公式为n/8字节(n为向量维度),例如128维二进制向量仅需16字节,远低于同等维度浮点向量的存储需求。该类索引支持JACCARD和HAMMING两种距离度量方式,主要包含两种典型实现:BIN_FLAT和BIN_IVF_FLAT。
| 索引类型 | 适用场景 | 支持的距离度量 | 存储效率 | 核心特点 |
|---|---|---|---|---|
| BIN_FLAT | 小数据集、需100%召回率、无需压缩的场景 | JACCARD、HAMMING | n/8字节(n为向量维度) | 精确检索,与FLAT原理一致 |
| BIN_IVF_FLAT | 高速查询、高召回率的场景 | JACCARD、HAMMING | n/8字节(n为向量维度) | 基于IVF结构,通过量化加速查询 |
其中,BIN_FLAT索引与FLAT索引原理一致,专为二进制嵌入设计,适用于小数据集、需100%召回率且无需压缩的场景;BIN_IVF_FLAT则基于倒排文件(IVF)结构,通过量化加速查询过程,适合对查询速度和召回率均有较高要求的场景。在选型边界方面,二进制嵌入索引与浮点索引的核心区别由向量类型决定:当处理对象为二进制向量时,应优先选择二进制嵌入索引以充分发挥其存储效率优势;若向量为浮点类型,则需采用浮点索引类型。
稀疏嵌入的核心特征是向量中非零值占比极低,这种稀疏性使其在存储和计算上具有独特优势,但也对索引结构提出了特殊要求。稀疏嵌入索引主要支持内积(IP)和BM25(全文检索)度量方式,目前主流的索引类型包括SPARSE_INVERTED_INDEX和SPARSE_WAND两种。
| 索引类型 | 适用场景 | 召回率 | 性能特点 | 关键参数 |
|---|---|---|---|---|
| SPARSE_INVERTED_INDEX | 小数据集 | 100% | 确保完全召回,大规模数据效率有限 | 无 |
| SPARSE_WAND | 需平衡速度与召回率场景 | 接近100% | 弱-AND算法加速,向量密度增加时性能下降,通过参数调整精度与性能平衡 | drop_ratio_search(范围[0,1]) |
SPARSE_INVERTED_INDEX(稀疏反转索引)适用于小数据集场景,其设计目标是确保100%的召回率,即在检索过程中不会遗漏任何相关结果,但在处理大规模数据时效率相对有限。
SPARSE_WAND(稀疏弱AND索引)则通过引入弱-AND(Weak-AND)算法实现性能优化。该算法的核心机制是减少对完整内积(IP)距离的计算次数:通过预设阈值筛选出对距离计算贡献较大的非零维度,仅对这些关键维度进行计算,从而显著提升检索速度。然而,SPARSE_WAND的性能表现与向量密度密切相关——当向量密度(非零值比例)增加时,需要计算的维度增多,弱-AND算法的筛选效率下降,导致性能出现衰减。为平衡检索精度与性能,SPARSE_WAND提供了drop_ratio_search参数(取值范围为[0,1]),该参数通过设置忽略小值的比例,进一步减少参与计算的非零维度数量,从而在牺牲少量召回率的前提下提升检索效率。
GPU索引通过利用GPU的并行计算能力,显著提升向量索引构建与搜索过程的吞吐量,尤其适用于极高吞吐量场景,但其加速效果主要体现在数据处理规模上,不一定能直接减少单次查询的延迟。不同类型的GPU索引在内存占用、精度、查询性能等方面各具特性,适用于不同业务需求场景。
| 索引类型 | 内存占用情况 | 精度/召回率 | 主要特点 | 适用场景 |
|---|---|---|---|---|
| GPU_CAGRA | 约为原始数据的1.8倍 | - | 基于图结构优化,提供丰富构建(如intermediate_graph_degree)与搜索参数(如itopk_size),低延迟表现突出 | 极高吞吐量场景,对延迟敏感的业务需求 |
| GPU_IVF_FLAT | 与原始数据等大 | - | 查询时间随nq(输入向量数)和nprobe(搜索簇数)增加急剧上升 | 中小规模查询场景 |
| GPU_IVF_PQ | 取决于压缩参数,小于IVF_SQ8 | 精度损失较大 | 通过向量压缩降低内存占用,索引文件较小 | 内存资源有限且可接受一定精度损失的场景 |
| GPU_BRUTE_FORCE | 与原始数据等大 | 100% 召回率 | 暴力搜索,仅需配置metric_type和top_k参数 | 对结果准确性要求极高、数据规模较小的场景 |
GPU_CAGRA是基于图结构的GPU优化索引,其内存使用量约为原始数据的1.8倍。该索引提供了丰富的构建与搜索参数以平衡性能,例如构建阶段可通过调整intermediate_graph_degree(剪枝前图度数,推荐32或64)、graph_degree(剪枝后图度数,需小于前者)、build_algo(支持IVF_PQ或NN_DESCENT算法)等参数优化图结构;搜索阶段则可通过itopk_size(中间结果大小,至少为目标top_k且通常设为2的幂次)、search_width(入口点数量)、迭代次数范围(min_iterations/max_iterations)等参数控制搜索效率与精度。由于其图结构优化和并行计算适配性,GPU_CAGRA在低延迟场景中表现突出。
GPU_IVF_FLAT的原理与CPU版本的IVF_FLAT类似,需占用与原始数据等大的内存空间。其查询时间对输入向量数量(nq)和搜索簇数(nprobe)较为敏感,两者的增加会导致查询时间急剧上升,因此更适合中小规模查询场景。
GPU_IVF_PQ通过向量压缩降低内存占用,其索引文件大小小于IVF_SQ8,但会引入一定的精度损失,内存占用量取决于具体的压缩参数配置,适用于内存资源有限且可接受一定精度损失的场景。
GPU_BRUTE_FORCE采用暴力搜索方式,能够实现100%的召回率,但其内存需求与原始数据相当,且仅需配置metric_type(距离度量类型)和top_k(返回结果数量)两个核心参数,适用于对结果准确性要求极高、数据规模较小的场景。
在高并发场景中,GPU索引凭借并行计算优势可高效处理大量并发查询,显著提升系统整体吞吐量。然而,其应用需权衡硬件成本:GPU设备本身购置成本较高,且不同索引对内存容量要求各异(如GPU_CAGRA需1.8倍原始数据内存,GPU_IVF_FLAT与GPU_BRUTE_FORCE需等大内存),因此需结合业务对延迟、召回率、吞吐量的需求及硬件预算综合选择。
ANNS向量索引的核心性能指标是评估和选择索引方案的基础,主要包括构建时间、每秒查询次数(QPS)、召回率及内存使用量。其中,构建时间指索引创建过程所消耗的时间,直接影响索引的初始化效率;每秒查询次数(QPS)反映搜索操作的效率,即单位时间内可处理的查询请求数量;召回率衡量搜索结果的准确性,体现返回的相关结果占所有相关结果的比例;内存使用量则表征索引对系统内存资源的占用情况,其大小受数据结构设计、量化压缩策略及精炼器等因素影响。
通过代码实践,我们可以直观地观察不同索引在定量数据集上的表现:

在实际应用中,需根据场景需求明确各指标的优先级逻辑。例如,实时应用(如在线推荐、实时检索服务)对响应速度要求严苛,QPS通常作为核心优先级指标;离线分析场景(如大规模数据挖掘、批量检索任务)更注重结果的完整性和准确性,此时召回率应优先考虑;而构建时间和内存使用量需结合资源约束进行权衡,如高频更新的动态数据集对构建时间敏感,资源受限的边缘设备则需重点关注内存占用。通过建立包含上述指标的评估框架,可实现对索引性能的量化分析,为后续索引选择决策提供客观依据。
ANNS向量索引的选择需遵循“速度-精度-内存”三角权衡模型,即提升某一维度性能往往以牺牲其他维度为代价。以下结合具体索引案例分析其内在规律:
在速度(查询效率) 维度,基于图的索引(如HNSW)通常表现更优,其QPS(每秒查询次数)普遍高于IVF系列变体。这一优势在小topK(如小于2000)场景中尤为显著,而当topK较大(如大于2000或占数据集比例≥1%)时,IVF变体因分桶机制更适配批量查询需求。此外,过滤率(搜索前过滤数据比例)也影响速度表现:过滤率<85%时图索引效率占优,85%-95%时IVF更合适,>98%时则需采用暴力搜索(FLAT)以平衡精度与计算成本。
精度(召回率) 方面,量化技术(如PQ、SQ)是内存优化的主要手段,但会导致精度损失。相同压缩率下,PQ较SQ能保留更高召回率,但查询速度略慢;而IVF系列(如IVF-PQ)虽通过量化显著降低内存占用,其召回率通常低于非量化索引(如HNSW)。对于极致精度需求(如过滤率>98%),FLAT索引仍是唯一选择,因其无近似计算误差。
内存占用 是资源受限场景的核心考量。IVF系列(如IVF-PQ)通过乘积量化技术实现高效压缩,内存消耗仅为11MB/百万128维向量,远低于HNSW的640MB/百万128维向量。对于超大规模数据集,DiskANN可通过磁盘存储管理数据,但需注意潜在的IOPS瓶颈对查询速度的影响。
| 索引类型 | QPS表现 | 召回率适用过滤率 | 内存占用(128维向量/百万) | 适用场景 |
|---|---|---|---|---|
| HNSW(图索引) | 通常优于IVF变体 | <85% | 640MB | 小topK(<2000)、高召回率、高吞吐低延迟场景 |
| IVF变体 | 低于HNSW | 85%-95% | 取决于量化技术 | 大topK(>2000或≥数据集1%)、批量查询 |
| IVF-PQ | - | - | 11MB | 内存受限场景,需结合mmap |
| FLAT | 最低(暴力搜索) | >98% | 最高(无压缩) | 极致精度需求,过滤率>98% |
| DiskANN | 受IOPS瓶颈影响 | - | 磁盘存储,内存占用低 | 超大规模数据集,磁盘级数据管理 |
在选择ANNS向量索引时,需综合考虑多维度决策关键因素,这些因素可系统地分为数据特性、资源约束和业务需求三大类,并需建立清晰的优先级排序逻辑以指导选择过程。
为帮助用户系统选择适合的ANNS向量索引,可基于实际应用场景构建决策矩阵,并将其转化为分步骤筛选流程。以下为整合后的推荐索引决策矩阵:
| 场景 | 推荐索引 | 注释 |
|---|---|---|
| 原始数据适合内存 | HNSW、IVF+精炼 | HNSW适合低k/高召回率 |
| 原始数据在磁盘/固态硬盘 | DiskANN | 适合延迟敏感查询 |
| 原始数据在磁盘且RAM有限 | IVFPQ/SQ+mmap | 平衡内存与磁盘访问 |
| 高过滤率(>95%) | FLAT(暴力) | 避免候选集过小的索引开销 |
| 大型k(≥数据集的1%) | IVF | 簇剪枝减少计算量 |
| 极高召回率(>99%) | FLAT+GPU | -- |
基于上述矩阵,索引选择流程可分为以下步骤:首先,判断数据存储位置及内存适配情况。若数据可完全加载至内存,优先考虑HNSW(适用于低k值、高召回率场景)或IVF+精炼组合;若数据存储于磁盘或固态硬盘且对查询延迟敏感,选择DiskANN;若数据在磁盘且内存资源有限,则采用IVFPQ/SQ结合内存映射(mmap)以平衡内存占用与磁盘访问效率。其次,考虑查询特性与需求:当过滤率超过95%时,FLAT(暴力搜索)可避免索引带来的额外开销;当查询k值较大(≥数据集规模的1%),IVF通过簇剪枝能有效减少计算量;若需极高召回率(>99%),建议使用FLAT+GPU方案。
此外,需注意例外情况:在GPU环境下,应优先考虑GPU加速的索引(如GPU_CAGRA),以充分利用硬件算力提升查询性能。通过上述流程,可根据具体场景快速定位最优索引方案。
核心索引参数的调优是平衡向量检索系统召回率、查询性能(如QPS)及资源消耗的关键环节。不同类型的ANNS索引具有独特的核心参数,其调整机制直接影响索引的构建效率、查询速度及检索精度。
| 索引类型 | 参数名称 | 参数作用 | 推荐值范围 | 性能影响 |
|---|---|---|---|---|
| IVF系列 | nlist | 决定向量空间聚类划分粒度 | 百万级数据1024 | 增大可提升搜索速度,但可能降低召回率 |
| IVF系列 | nprobe | 控制查询时遍历的簇数量 | 8-100 | 增大可提高召回率,但会增加查询时间 |
| HNSW | M | 图中每个节点的连接度数 | 16-48 | 增大可提升检索精度,但增加构建时间和内存占用 |
| HNSW | efConstruction | 索引构建阶段的搜索范围参数 | 200-500 | 增大可提升索引质量,但延长构建时间 |
| HNSW | ef | 查询阶段的搜索范围参数 | top_k-2000 | 增大可提高搜索精度,但降低查询速度 |
| SCANN | reorder_k | 重排序候选向量数量 | top_k-1000 | 增大可提高召回率,但增加计算量和查询时间 |
| 稀疏索引 | drop_ratio_search | 查询时忽略小值元素的比例 | - | 调整可在精度与性能之间取得平衡 |
在向量索引的实际部署中,内存与存储资源的高效利用是关键挑战之一。以100万128维向量为例,不同索引类型的内存占用差异显著,如IVF_PQ索引仅需10MB左右的内存,而HNSW_PQ索引则需136MB,这种差异凸显了优化策略的重要性。
内存规划可遵循以下步骤:首先,根据数据集规模(如向量数量、维度)和选定的索引类型(如IVF、HNSW等)估算基础内存需求。若估算结果超出可用内存,则需采用针对性优化手段。常用策略包括量化、内存映射(mmap)及磁盘存储方案(如DiskANN)。
| 优化策略 | 技术方法 | 效果描述 |
|---|---|---|
| 量化 | PQ(乘积量化) | 实现64倍压缩 |
| 量化 | SQ(标量量化) | IVF_SQ8索引减少75%内存消耗 |
| 内存映射(mmap) | 直接访问磁盘文件 | 减少I/O开销,扩展存储容量 |
| DiskANN | 图结构存储于磁盘 | 处理内存无法容纳的超大型数据集 |
量化技术通过压缩向量表示降低内存占用,典型方法包括乘积量化(PQ)和标量量化(SQ)。例如,PQ可实现64倍压缩,而IVF_SQ8索引通过标量量化能减少75%的内存消耗。内存映射(mmap)技术允许直接访问磁盘文件,在减少I/O开销的同时扩展存储容量,适用于内存资源有限但磁盘空间充足的场景。对于内存无法容纳的超大型数据集,可采用DiskANN等磁盘存储方案,将图结构存储于磁盘以处理大规模数据。通过结合上述策略,可在保证检索性能的前提下,有效降低内存与存储成本。
首先,什么是 “mmap”?
“mmap” 全称 “内存映射”,可以简单理解为:给硬盘上的大文件在内存中开一个 “直接窗口”。
举个例子:比如我们有一段非常大的素材文件,有20GB,我们要打开这个文件就需要20GB的内存,但我们电脑并没有这么大的内存,怎么办呢,此时mmp应运而生,mmp为这个大文件打开了一个内存窗口,可以直接访问到SSD中的文件,就像该文件已经在内存中一样,这样我们就可以直接访问该文件了,而不需要把整个文件加载到内存中。
而对于Milvus这种非常吃内存的数据库,加载一个集合时,会把所有的标量字段、向量字段和索引等全部加载到内存中,如果数据量太大,还会出现加载失败的问题,使用mmp优化存储后,我们可以加载一个非常大的Collection到内存中,并且在不占用太大的内存的情况下,就可以处理这类大规模的向量数据。
mmp是怎么实现的呢?
在使用mmp时,每次加载Collection时,Milvus会调用mmap将用于保障搜索速度的关键的索引加载到内存中,而其他的标量或者向量数据将会继续存放在SSD中,查询时,将通过内存映射的方式访问数据。
注意点:
性能可能波动:如果访问的数据不在内存缓存里(比如第一次访问某个冷数据),需要从硬盘读,速度会比纯内存慢一点(这叫 “缓存未命中”)。
索引仍需内存:为了保证搜索速度,索引还是要加载到内存,不能映射到硬盘。
mmap 的配置级别(怎么用?)
Milvus 的 mmap 可以在 4 个级别配置,优先级从高到低是:字段 / 索引级别 > 集合级别 > 全局级别(优先级高的会覆盖低的)。
milvus.yaml中的,storage参数,将mmapEnabled设置为true# milvus.yaml storage: mmapEnabled: true # 全局启用 mmap mmapDirPath: /opt/milvus/data/mmap_files # 映射文件存储路径
举例:给 大大大数据集 这个集合启用 mmap,就能单独让它的数占内存少一点。
from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection # 连接 Milvus connections.connect("default", host="localhost", port="19530") # 创建集合时启用 mmap fields = [ FieldSchema(name="id", dtype=DataType.INT64, is_primary=True), FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=128), FieldSchema(name="description", dtype=DataType.VARCHAR, max_length=1000) ] schema = CollectionSchema( fields, description="大大大数据集", properties={"mmap.enabled": "true"} # 关键配置:集合级启用 mmap ) collection = Collection("Dw_easy_db", schema) # 修改已有集合的 mmap 配置 coll = Collection("Dw_easy_db") coll.release() # 必须先释放集合 # 修改 mmap 属性并重新加载 coll.alter_properties({"mmap.enabled": "false"}) # 关闭 mmap coll.load()
# 创建字段时启用 mmap(需 Milvus v2.3.0+) fields = [ FieldSchema(name="id", dtype=DataType.INT64, is_primary=True), FieldSchema( name="large_text", dtype=DataType.VARCHAR, max_length=65535, properties={"mmap.enabled": "true"} # 字段级启用 mmap ) ] # 修改已有字段的 mmap 属性 coll = Collection("text_collection") coll.release() # 修改字段属性 coll.alter_field("large_text", {"mmap.enabled": "false"}) # 关闭该字段 mmap coll.load()
# 创建索引时启用 mmap index_params = { "index_type": "IVF_FLAT", "metric_type": "L2", "params": {"nlist": 1024}, "properties": {"mmap.enabled": "true"} # 索引级启用 mmap } coll = Collection("vector_collection") coll.create_index("vector", index_params) # 修改索引 mmap 属性 coll.release() coll.alter_index("vector_index", {"mmap.enabled": "false"}) # 关闭索引 mmap coll.load()
Milvus 官方建议:常用的数据和索引一定要放内存,不常用的再用 mmap。
比如:
高频访问的 “用户画像向量” 和其索引 —— 放内存,保证搜索快。
低频访问的 “历史日志向量”—— 用 mmap,存硬盘省内存。
在处理十亿级规模的超大规模向量数据集时,由于内存资源通常无法完全容纳全部数据,需依赖磁盘存储与内存访问的协同优化。DiskANN是应对此类场景的关键技术之一,其核心原理是通过磁盘存储Vamana图结构,并结合乘积量化(PQ)压缩技术,实现对内存无法容纳的超大规模数据集的高效检索。这种“磁盘图结构+压缩存储”的设计,既能突破内存容量限制,又能通过PQ量化减少数据传输与存储开销。
在延迟表现方面,与基于内存映射(mmap)的方案(如IVF_PQ/SQ+mmap)相比,DiskANN的延迟更为稳定。mmap方案虽通过内存映射平衡内存占用与磁盘访问,但磁盘I/O的随机性可能导致延迟波动;而DiskANN通过优化的图遍历策略与预取机制,可减少磁盘访问的不确定性,从而提供更一致的响应延迟。
针对十亿级数据集的索引组合方案,实践中主要有两类选择:一是采用DiskANN结合PQ量化,利用磁盘存储图结构并通过PQ压缩向量,适用于极致内存受限场景;二是使用IVF_PQ/SQ与mmap结合,通过IVF的粗聚类减少检索范围,配合PQ/SQ量化降低内存占用,同时借助mmap实现磁盘数据的高效内存访问,在内存与延迟之间取得平衡。具体选择需根据实际内存资源、延迟需求及数据特性综合考量。
在高并发低延迟场景中,向量索引的选择需重点平衡查询吞吐量、响应时间与资源成本。基于图的索引(如HNSW)凭借对数时间复杂度的搜索特性,以及DiskANN针对延迟敏感查询的优化设计,成为该场景下的核心选择。此外,GPU加速索引(如GPU_CAGRA)通过硬件并行计算能力,可显著提升高并发处理效率。
| 索引类型 | 技术特点 | 适用场景 | 优化参数 |
|---|---|---|---|
| HNSW | 基于图的对数时间搜索 | 低延迟需求 | ef(探索节点数) |
| DiskANN | 针对延迟敏感查询优化 | 低延迟需求 | - |
| GPU_CAGRA | GPU加速并行计算 | 高并发、批量查询(nq>1000) | search_width(搜索宽度) |
从硬件性价比角度看,CPU与GPU的适用场景存在差异:GPU更适合处理批量查询规模较大(nq>1000)的高并发场景,其并行计算架构能有效降低单位查询的处理延迟;而CPU在小规模查询或资源受限环境中可能更具成本优势。
| 硬件类型 | 适用场景 | 优势 | 限制 |
|---|---|---|---|
| CPU | 小规模查询、资源受限环境 | 成本优势 | 并行处理能力有限,高并发下延迟较高 |
| GPU | 批量查询规模较大(nq>1000) | 并行计算架构,降低单位查询处理延迟 | 资源成本较高,小规模查询性价比低 |
针对低延迟优化,实践中可采用“索引类型+参数调优+硬件加速”的组合策略。例如,HNSW索引可通过增大ef(查询时的探索节点数)参数提升搜索效率,GPU_CAGRA则可调整search_width(搜索宽度)参数平衡延迟与召回率。结合GPU加速技术,此类组合能在保证高召回率的同时,满足毫秒级甚至微秒级的低延迟需求。
FLAT与IVF_FLAT的核心差异在于检索方式:FLAT索引通过直接比较查询向量与数据集中所有向量获得精确结果,而IVF_FLAT索引先将向量聚类为nlist个簇,查询时仅比较距离最近的nprobe个簇内向量以减少计算量。当数据集向量总数接近nlist时,IVF_FLAT的聚类优势不明显,性能与FLAT相近;当向量数量远大于nlist时,IVF_FLAT通过减少比较次数显著提升效率。此处nlist(聚类簇数量)和nprobe(查询时检查的簇数)需协同调整:nlist过小会导致簇内向量过多,削弱加速效果;nprobe过大会增加计算量,接近FLAT的性能。
| 索引类型 | 检索方式 | 比较向量范围 | 性能关键参数 | 性能特点 | 适用场景 |
|---|---|---|---|---|---|
| FLAT | 直接比较所有向量 | 全部向量 | 无 | 精确结果,计算量大,性能随数据量线性下降 | 小数据集,对精度要求极高的场景 |
| IVF_FLAT | 先聚类为nlist个簇,查询时比较nprobe个簇内向量 | 距离最近的nprobe个簇内向量 | nlist(簇数量)、nprobe(查询簇数) | 近似结果,计算量减少,数据量远大于nlist时优势显著 | 大数据集,需平衡精度与速度的场景 |
PQ与SQ的压缩率差异体现在量化粒度:标量量化(SQ)如IVF_SQ8对每个向量维度独立压缩,将4字节浮点值转为1字节整数,内存占用减少75%;乘积量化(PQ)如IVF_PQ(以8个子量化器为例)将向量分割为子向量后分别量化,可将512字节向量压缩至8字节,实现64倍压缩率。两者相比,PQ压缩率远高于SQ,但可能伴随更高的精度损失。
压缩倍数对比数据:
| 量化策略 | 压缩方式 | 原始大小 (每向量) | 压缩后大小 (每向量) | 内存减少比例 | 压缩倍数 |
|---|---|---|---|---|---|
| IVF_SQ8 | 标量量化,每个维度独立压缩 | 4字节/维度 | 1字节/维度 | 75% | 4倍 |
| IVF_PQ | 乘积量化,8个子量化器分割向量 | 512字节 | 8字节 | 约98.44% | 64倍 |
避坑指南方面,小数据集应避免过度量化:由于数据量有限,FLAT或IVF_FLAT索引已能满足性能需求,使用IVF_PQ等强压缩索引反而可能因信息损失导致精度下降。此外,配置IVF类索引时需根据数据规模合理设置nlist(建议为数据量的平方根量级),并通过nprobe平衡召回率与速度(默认值通常为10,需根据精度需求调整)。
距离度量方式是判断两个向量相似程度的核心标准,通过计算向量空间中两个向量的“距离”或“相似度”量化关联程度。不同类型的向量(文本、图像、音频)、不同模型编码的向量,需匹配对应的距离度量方式才能保证检索效果。Milvus支持多种距离度量方式,核心常用类型如下:
关于这一部分,我们说的是你在使用milvus的场景下!
当选择欧氏距离作为距离度量时,Milvus 只计算应用平方根之前的值。
这意味着Milvus在计算欧氏距离时会跳过开平方根的步骤,只计算平方和的结果。
这样做的好处是:
所以虽然数值上不是真正的欧氏距离,但在向量相似性搜索中,这种优化不会影响搜索结果的准确性。

两个向量在相同维度空间中的一种运算,结果是一个标量(单个数字)。值越大(正值),表示方向越接近;值为 0 表示正交(垂直);值为负表示方向相反。它也间接包含了向量长度信息(模长)。
归一化是把向量中的元素缩放到一个固定的范围,比如0到1。
公式:
对于向量 V = [v₁, v₂, ..., vₙ],其 L2 范数为 ||V||₂ = √(v₁² + v₂² + ... + vₙ²)。归一化后的向量 V_norm 为:V_norm = V / ||V||₂ = [v₁/||V||₂, v₂/||V||₂, ..., vₙ/||V||₂]
归一化的核心作用是让向量的长度变为1,但方向不变。这在很多场景下非常重要,因为:
例如,假设你有一个向量 V = [3, 4]:
长度 = ||V||₂ = √(3² + 4²) = 5V_norm = [3/5, 4/5] = [0.6, 0.8]||V_norm||₂ = √(0.6² + 0.8²) = 1Milvus官方建议:对于归一化向量,欧氏距离(L2)在数学上等同于内积(IP)。如果这些相似性度量返回不同的结果,请检查您的向量是否归一化。
欧氏距离和内积是两种常用的距离度量方式,选择L2还是IP,主要取决于你的具体任务和对相似性的定义:
对于欧氏距离L2来说,其核心思想是衡量两个点之间在空间中的绝对距离。
对于内积IP来说,其核心思想是衡量两个点之间的方向关系。
在计算复杂度上,L2和IP的计算复杂度都是O(d),其中d是向量的维度。但L2比IP多做了n次减法和1次开平方根运算,对于单次计算,L2的开销要比IP要高,但这种差异在绝大多数场景下均是可忽略的。
选择建议:
本章核心掌握Milvus数据模型与索引体系的核心逻辑,重点包括:
这些概念是后续Milvus实操(集合创建、数据插入、索引构建、相似性检索)的基础,需重点理解各组件的依赖关系与设计初衷,才能在实际业务中灵活设计数据结构与检索方案。