RAG 与向量数据库 · C 向量库内核
0 / 8 章 ← 首页
贯穿案例 · 一家公司的客服知识库 序幕 · 十篇文档的原型 第二幕 · 答得不准,调质量 第三幕 · 一千万篇,扛规模 第四幕 · 上线,选型与实战 第五幕 · 活下去,更新与治理
01

向量形态与物理账单 —— 为什么需要专门的数据库

在深入讨论千万级向量如何检索之前,必须先揭开向量的物理本质:向量不是玄学概念,而是一组定长的高维浮点数坐标。它的维度、存储精度以及底层索引结构,直接决定了整个知识库的成本与速度边界。

维度(Dimension)是什么?能决定什么?

通俗地说:如果给一个人建档,只记录【身高、体重】就是 2 个维度;如果再加上【年龄、学历、收入、发量、性格偏好……】就变成了高维。向量里的每一个维度,就是一条抽象的语义特征坐标轴。

决定 ①语义表达细腻度

维度越高,向量在几何空间中的“表达空间”越大,越能区分微妙的语义差异(例如区分“轻微剐蹭”与“严重追尾”)。但维度过高也会带来“高维诅咒”,导致距离区分度被稀释。

决定 ②计算与传输倍率

维度与计算量成正比。维度翻倍,向量占用的内存、外存体积翻倍,每次计算点积/余弦相似度的 CPU 乘加操作次数也直接翻倍。

原则 ③维度由模型决定

重点:维度不是向量数据库随手配置的,而是由生成它的嵌入模型(Embedding Model)决定的!换模型必须整库重算向量,无法直接混用。

2026 年常见维度该怎么选?

维度区间代表模型(2026 年主流)单向量大小 (fp32)最佳适用场景
256 ~ 384 维all-MiniLM-L6-v2、BGE-small≈ 1 ~ 1.5 KB移动端、边缘设备、轻量 Agent、百万级以内极致低延迟场景
512 ~ 768 维BERT、BGE-base、OpenAI text-embedding-3 截断档≈ 2 ~ 3 KB中小企业客服与知识库性价比甜点区,内存压力小
1024 维BGE-large、Qwen3-Embedding-8B、Voyage-3≈ 4 KB2026 工业生产落地的黄金标准,多语言及复杂语义召回强
1536 ~ 3072 维OpenAI text-embedding-3-large、大型闭源 API≈ 6 ~ 12 KB法律、学术、医疗等超高精度长文档;自建库内存开销极重
套娃截断(Matryoshka)2026 年的主流嵌入模型普遍支持套娃表示学习(Matryoshka Representation Learning)。模型在训练时就保证前 N 维(如 512 或 256)保留了大部分语义。你可以安全地丢弃后半段,存储直接减半,召回率通常仅微降 1%~2%(B 页第 2 章)。

精度(Precision)是什么?常见场景怎么选?

维度决定了“有几个数字”,而精度决定了“每个数字占几个字节”。计算机用不同格式的二进制存储浮点数,格式越精细,数字越准,但体积也越大。

存储精度单维字节压缩比召回影响2026 常见场景选型建议
float32 (单精度)4 字节1× (基准)无损 (0%)开发测试、< 100 万条小规模库,无需任何优化直接保真
float16 / bfloat162 字节2×极微 (< 0.2%)生产通用第一步:内存直接减半,现代 CPU/GPU 硬件原生加速
int8 (标量量化)1 字节4×很小 (≈ 1%~2%)千万级生产落地的首选标配,单机即可抗住千万向量
1-bit (二值量化/RaBitQ)0.125 字节32×较明显 (需精排)数千万至亿级超大规模:配合“粗筛 + 磁盘全精度精排”架构

常见的向量数据库(2026 年四大流派)

面对这批向量,市面上的向量数据库究竟该怎么理解?不要被上百种工具眼花缭乱,它们在底层内核上主要分为四个流派:

关系型扩展派 · 省心同库pgvector / pgvectorscale

在现有 PostgreSQL 里安装扩展,向量与业务数据同表、同事务、支持 ACID。适合已有 Postgres、数据量千万以内、强依赖元数据关联的团队。

原生专用分布式派 · 吞吐之王Milvus / Qdrant

底层从网络到存储全为向量定制。Milvus 支持万亿级分布式扩展与 GPU 加速;Qdrant 基于 Rust 开发,单机过滤速度与极低延迟表现出色。适合中大型高并发生产环境。

轻量与嵌入式派 · 极简无服务LanceDB / Chroma

类似 SQLite,无独立服务端进程,内嵌于应用代码中。LanceDB 基于原生列存,能直接高效读写本地磁盘甚至 S3 对象存储。适合本地开发、桌面应用、轻量 Agent。

全托管 / Serverless 派 · 零运维Pinecone / turbopuffer

云端开箱即用,按实际检索量计费。底层自动处理冷热分层与弹性伸缩。适合没有专职 DBA/运维、追求快速上线验证业务的团队。

遭遇规模危机:暴力搜索的真实账单

回到客服知识库案例:当手册切块从十篇膨胀到一千万个块时,原型里那句轻巧的 vectors @ q(拿查询向量和库里每一个向量算一次点积)彻底暴毙了:

LAB 1.1 · 规模计算器真实计算:内存占用与暴力扫描耗时下限
参数说明与公式:
• 原始向量大小 = 条数 × 维度 × 每维字节。
• HNSW 额外索引大小 ≈ 条数 × 2M × 4 字节(图结构指针出边开销)。滑块中的 M 代表节点在图中的出度上限,M 越大图越密、检索越准,但内存开销也按 M 线性暴增(第 3 章专门详解)。
• 暴力扫描耗时 = 向量总字节数 ÷ 内存带宽。这是纯读数据的物理下限,未计 CPU 浮点运算与调度损耗。
为什么算力不是瓶颈,内存带宽才是?以 1000 万条 1024 维 float32 向量为例,数据量是 40.96 GB。单次查询需要约 100 亿次浮点乘加(FLOPs),现代多核 CPU 每秒能算几千亿次,只需几毫秒;然而把这 41 GB 数据从内存条原原本本搬进 CPU 缓存,在 50 GB/s 的实际内存带宽下需要整整 0.82 秒!这属于典型的内存带宽受限(Memory-Bound)场景。单次查询卡顿近 1 秒,系统并发直接崩溃。
✦ 本章通关条件
✓
能解释「维度」与「精度」的区别,心算出 N 条 d 维向量的大小,并说明暴力搜索的瓶颈为什么是内存带宽
查看参考答案
大白话

维度是「身上贴了几个特征标签」(由模型定),精度是「每个标签写得多精细/占几个字节」。大小 = 条数 × 维度 × 字节数。一千万条 1024 维 float32 约 41 GB。暴力搜索像每次问路都把整座城市的电话簿从第一页翻到最后一页,慢在「把书从书架搬到桌上」(搬运带宽),而不是「眼睛看一眼」(计算)。

专业版

维度决定特征空间容量,由嵌入模型架构确定;精度是数值表示类型(FP32/FP16/INT8/1-bit)。数据大小公式为 N·d·bytes。点积计算每读取 4 字节仅产生 2 次浮点操作,算术强度极低(≈ 0.5 FLOP/byte),受冯·诺依曼架构内存总线吞吐封顶,属于典型 Memory-Bound 任务。

承上启下 既然全量暴力扫描不可承受,我们该如何破局?
向量数据库的全部智慧,就在于放弃 100% 精确,用「近似最近邻(ANN)」换取几个数量级的吞吐飞跃。如果不想每次把几百万本书逐本翻一遍,最符合直觉的偷懒办法是什么?——“在空间里设立分类展台(聚类分桶),查询时先找最近的几个展台,然后只翻这几个展台的书架,其余 99% 统统跳过”。这就是下一章要拆解的 IVF(倒排文件索引)。
02

IVF 倒排索引 —— 空间聚类分桶:先查大类展台,再搜具体货架

面对千万级向量,逐个比对的暴力穷举会迅速击穿内存与算力带宽。IVF(Inverted File Index,倒排文件索引)的核心思想就像大型物流仓储或国家图书馆的管理智慧:绝不让你盲目翻找 1000 万件货物,而是先在空间中设立若干个「分类大展台」,找东西时先花极小代价锁定最近的 2~3 个展台,然后只深入这几个展台所属的货架搜寻,其余 99% 的货架统统跳过!

破除专业名词迷雾:为什么连续向量也要叫「倒排索引」?

在传统搜索引擎(如 Elasticsearch)中,“倒排”指的是 单词 Token → [包含该词的文档 ID 列表]。向量明明是一串连续的高维浮点数组,为什么也被称为“倒排文件(IVF)”?

传统正排视角(查谁算谁) 向量 ID → 坐标数据

vec_1: [0.21, -0.44, ...]
vec_2: [-0.08, 0.72, ...]
要找谁和查询向量最相似?必须把全库所有向量 ID 从头到尾挨个调进内存算点积,无法做任何粗筛剪枝。

IVF 倒排视角(分桶反查) 质心桶 ID → [所属向量 ID 链表]

Centroid_#1 (科技展台) → [vec_12, vec_89, ...]
Centroid_#2 (体育展台) → [vec_03, vec_44, ...]
把高维连续空间聚类离散化成一个个“桶”,查询时先定位最近的桶,然后倒查桶里的向量!

两阶段工作流:离线归槽与在线剪枝

阶段 1 · 空间画桶(离线建索引) K-Means 选出 nlist 个质心

算法在向量空间中聚类选出 nlist 个最具代表性的中心点(称为质心 Centroid)。全库所有向量计算自己离哪个质心最近,自动投递进该质心的「专属收纳桶(倒排链表)」。

阶段 2 · 极速粗排(在线查质心) 只算 nlist 次点积,锁定目标桶

用户携带 Query 向量进来时,绝不碰全库上千万原始向量,先只与这 nlist 个质心算距离(仅几百次运算,耗时 <0.05ms),选出距离最近的 nprobe 个质心桶。

阶段 3 · 局部细排(跳过 99% 算力) 只在选中的几个桶内比对

系统直接将剩下 95%~99% 的桶完全忽略剪枝,只把这 nprobe 个桶里的向量拉出来计算精确相似度并排序。以极其轻微的精度损失,换取百倍级的吞吐提速!

两大核心调优旋钮:nlist 与 nprobe 怎么选?

参数名称设定阶段通俗解释与物理意义极端取值与后果2026 工业选型经验法则
nlist 建索引时(不可变) 空间一共切分成多少个「分类展台 / 质心桶」。 设太小(如 4)每个桶过大退化为全库暴搜;设太大(如 100 万)光比对质心就耗尽时间。 经验公式推荐 4√N 到 16√N。
例:100 万向量通常设 4096。
nprobe 每次查询时(动态可调) 查询时深入翻查多少个最近的「展台货架」。 nprobe = 1 速度极快但极易漏检;nprobe = nlist 退化为 100% 穷举全搜。 推荐设为 nlist 的 1% ~ 5%(如 4096 个桶中探查 16~64 个)。

致命死穴:为什么片区边界会翻车?(高维表面积灾难)

在下方的二维实验中,你可能会觉得“片区分割很直观,大部分点都在质心附近”。但在真实工业生产的高维空间(768 或 1536 维)中,IVF 面临一个无法违抗的几何宿命——维度灾难与测度集中(Measure Concentration):

  • 球心是空的,高维数据点 99.9% 挤在边界外皮上:在高维超球体中,根据几何测度定理,超球体的体积几乎全部集中在紧贴最外层表面的一层微薄外壳上。这意味着在 768 维空间中,几乎所有向量都挤在不同片区的「分界墙」附近,而不是在质心中央!
  • 一墙之隔的真近邻被彻底漏检:如果你的查询向量 Query 恰好落在片区 A 的边缘(离边界仅 0.01),而全库离它最近的 Top-1 真近邻恰好落在隔壁片区 B 的边缘(两者相距仅 0.02)。如果 nprobe 比较保守没有把片区 B 选入探测范围,这个近在咫尺的真近邻就会被100% 永久漏检!
  • 探查雪崩(The Probe Explosion):为了捞回这些边界附近的漏检,你只能被迫增大 nprobe。但在高维空间中,相邻片区的数量呈指数级激增!为了达到 98% 以上的召回率,往往必须探查全库 20%~30% 以上的桶——此时原本期望的百倍提速急剧缩水至仅剩 3~4 倍,算力优势荡然无存!
LAB 2.1 · IVF 片区探测真实 k-means(3000 点,10 轮迭代),召回对 80 个查询取平均
查询点找到的真近邻漏掉的真近邻亮色区域 = 被探测的片区
点击画布可更换查询点。下方柱状图展示在当前 nlist 下,nprobe 取 1~10 时的平均召回率(绿柱)与扫描数据比例(红线)。把 nprobe 调大,召回上升但扫描比例急剧增加——为了追求 98% 以上的高召回,往往要扫描 20% 甚至更多数据,提速倍数大打折扣。
✦ 本章通关条件
✓
能解释 nlist 与 nprobe 各自控制什么,并说出高维空间下 IVF 召回丢失发生在何处
查看参考答案
大白话

nlist 是把仓库总共划成几个分类展台(建库定死),nprobe 是找东西时愿意深入翻查最近的几个展台书架(查询时可随心调)。为什么会漏检?因为你要找的最相似货物正好摆在隔壁展台的最外侧,而你的 nprobe 没选隔壁展台,就彻底错过了。在高维空间里,大部分数据都挤在展台边界墙附近,想找全就必须多翻很多展台,速度大幅下降。

专业版

nlist 为 K-Means 聚类簇数(构建期质心数),nprobe 为查询期动态探测的 Voronoi 胞腔数。高维空间中几何测度集中导致数据点绝大部分分布在胞腔超曲面边界附近。当 Query 与真近邻分属不同胞腔且后者未被 nprobe 命中时即发生边界漏召。工程上常以 nlist ≈ 4√N 构建,在线通过增大 nprobe 或辅以重排提升召回。

承上启下 打破片区死板边界:从“行政区划”到“人际关系网”
既然划死板的片区容易在交界处翻车,能不能换一种思路——不划死片区,而是让每个点直接结识距离它最近的几个好友,形成一张人际关系网络?查询时从某个熟人出发,顺着朋友圈逐级引荐、一路向目标靠拢!这就是在当代向量数据库中占据统治地位的图索引——HNSW。
03

HNSW —— 在多层「朋友圈」里顺藤摸瓜

HNSW 全称 Hierarchical Navigable Small World(分层可导航小世界图)。它是过去五年工业界最主流的向量索引,也是 pgvector、Milvus、Qdrant 等系统默认的首选武器。

小世界网络与六度分隔:怎么“顺藤摸瓜”?

现实生活中有一条著名的“六度分隔理论”:你和世界上任何一个陌生人之间,平均只需要通过 6 个人就能建立联系。因为每个人的人脉圈里,既有身边的“密友(短距离连线)”,也有远在异地的“远亲或老同学(长距离长程连线)”。

图上的贪心搜索:从图的某一个固定入口点出发,问它的所有好友:“你们谁离目标查询最近?”挑出最近的那一个走过去,再问它的好友……如此反复迭代,步步逼近目标。这叫贪心路由(Greedy Routing)。

为什么必须分层(Hierarchical)?—— 跳表地图思想

如果只有单层网络,当数据量达到千万级时,贪心搜索很容易在密密麻麻的局部胡同里“原地打转”,步子迈得太慢,甚至掉进局部死胡同。HNSW 借鉴了计算机科学中的经典数据结构跳表(Skip-List),将网络构造成多层:

  • 顶层(高速公路 / 世界地图):只有极少量的“枢纽节点”,连线跨度极大,一步就能跨越半个向量空间,迅速缩短与目标的距离。
  • 中层(省道 / 城市地图):节点逐渐增多,快速收敛到目标所属的局部区域。
  • 底层 Layer 0(街道胡同 / 全量地图):包含 100% 的全部数据点,连线最为密集,在目标附近做最后的精细搜索。
LAB 3.1 · HNSW 搜索回放1000 个二维点,3 层结构;点击画布切换查询,拖动滑块回放路径
顶层路径(长程跨越大步走)中层路径(收敛区域)底层访问的点(局部精搜)返回的 top-10
尝试把 M 调小到 2:图的连通性急剧恶化,顶层容易断链,贪心搜索经常撞入死胡同,召回率明显崩塌。而把 ef 调大,底层候选池加深,召回率上升,但距离计算次数也会增加。

重点攻坚:核心参数 M 到底是什么意思?

在所有向量数据库的文档和配置中,M 都是出镜率最高的核心参数。它绝不是一个神秘的数字,用大白话解释:

定义M 是每个节点的好友上限

在构建索引时,M 规定了每个节点在各层图上最多能连几条出边(最多结交几个好友)。它直接定义了整张图的稠密程度。

为什么底层是 2M?防止孤岛与死胡同

在高层(粗筛层),每个点连 M 条边;但在最底层(Layer 0),因为要容纳 100% 全量数据,为了防止边缘点变成孤岛、确保局部高连通性,算法统一允许底层最多连 2M 条边!

致命代价内存开销与 M 严格成正比

图上的每条连边,在内存里都是一个 4 字节的节点指针。全库额外的图结构内存开销 ≈ N × (2M) × 4 字节。M 开得越大,服务器内存账单暴涨越凶!

参数三剑客协同指南:M、ef_construction 与 ef_search

参数名称作用阶段通俗解释与作用调大后的效果与代价2026 工业推荐值
M建索引时(不可变)每个节点的好友连线数(底层 2M)。决定图的骨架密度。召回上限更高,但内存按 M 线性暴增,建索引变慢。默认推荐 16(pgvector、Milvus 默认值);超高精取 32~64。
ef_construction建索引时(不可变)建图插入新节点时,在周围探索多少个候选者来挑选最优好友。建出的图质量更高、死胡同更少;不增加内存,只拖慢建索引时间。推荐 64 ~ 128(Milvus 常用 128,pgvector 默认 64)。
ef_search每次查询时(动态可调)在线搜索时,同时维护的优先级候选队列长度。召回率更高,但查询延迟上升;完全不增加内存。推荐 16 ~ 64;高峰期调小换 QPS,低峰期调大换召回。
✦ 本章通关条件
✓
能解释 HNSW 为什么分层,说出 M 的真实含义与底层 2M 的由来,并能心算 M 对内存的影响
查看参考答案
大白话

分层是为了「先坐飞机(顶层长程跳跃)、后打出租(中层定位)、最后步行(底层挨家挨户敲门)」。M 是每个人最多交几个朋友。底层放了全城所有人,为了不漏掉住在偏僻角落的人,底层好友名额翻倍成 2M。代价:朋友越多通信录越厚,每多一条边就多占 4 字节内存,所以 M 不能无限大,通常设 16。

专业版

分层借鉴跳表思想,获得 O(log N) 的对数级路由复杂度。M 控制图度数(Degree),底层为 2M 是为了保证密集基图的局部连通度(Delaunay 图逼近)并容纳更多反向边。额外图内存公式为 N·2M·4B。M 与 ef_construction 为构建期参数,ef_search 为查询期参数,可在运行时动态调节延迟与召回平衡。

承上启下 HNSW 极速背后的致命死穴:内存爆炸!
HNSW 查得飞快、召回率傲视群雄,是 2026 年毫无争议的黄金索引。但天下没有免费的午餐:HNSW 要求把所有原始向量和整张图结构全部常驻在 RAM 内存中!
算一笔现实账:1000 万条 1024 维 float32 向量(41 GB),加上 M=16 的图索引(1.3 GB)与运行时元数据,单机至少需要 64 GB 乃至 128 GB 高昂的物理内存。面对上亿级规模,内存成本会瞬间突破天际。
既然图索引已经帮我们做到了“少看几条数据”,面对内存大山,我们能不能从另一个物理维度下手——“把每一个向量本身,压得更小、少存几个字节”?这就引出了下一章的杀手锏:向量量化(Quantization)。
04

量化 —— 每个向量少存几个字节

前面两章的索引算法(IVF、HNSW)是在想办法「少看几条数据」(空间剪枝),而量化(Quantization)是在从另一个物理维度破局——「把每一条向量存小一点」(存储压缩)。一个 1024 维的 float32 向量原始大小为 4 KB;如果每一维只用 1 个比特来存,体积将骤降至 128 字节,直接缩小 32 倍!

常见的三大量化流派

主流标配 · 4×标量量化(SQ int8)

把浮点数区间等距离划分成 256 个桶,映射到单字节整数(0~255)。从 4 字节压到 1 字节,召回率损失极微(通常 < 1.5%),2026 年千万级中大规模生产落地的默认标配。

经典灵活 · 16~64×乘积量化(PQ)

把向量切成若干小子段(如 1024 维切成 128 段),每段训练一套聚类码本。每段只存 1 字节的码本索引编号。查询时通过查预计算距离表(ADC)极速计算,但需训练码本,召回损失稍大。

极限极致 · 32×二值量化(1-bit / RaBitQ)

每个维度仅记录正负(>0 记为 1,≤0 记为 0)。4 字节直接压缩为 1 比特!计算转化为单周期 CPU 汉明距离指令(POPCNT),每秒能比对上千万次。RaBitQ 进一步引入误差纠偏因子。

LAB 4.1 · 量化召回实测真实运行:3000 条 128 维合成向量,40 个查询,对比精确 top-10

点击运行,浏览器会现场进行量化编码并计算召回。「二值 + 精排」展示过采样(先圈出更多粗候选)再用全精度向量重排的效果:

数据为聚簇高斯向量,演示相对趋势。单个 128 维向量的 fp32 大小为 512 字节。观察重点:纯 1 比特由于信息损失大,召回率较低;但一旦配合 5× 或 10× 的过采样精排,召回率瞬间被拉回 95% 以上!

2026 生产黄金配方:“内存粗筛 + 磁盘全精度精排”

纯量化后由于距离被离散化,距离排序难免出现微小位移,原来排第 1 的可能被挤到第 8。工业界是如何在省下几十倍内存的同时保住 98%+ 召回率的?

阶段存放位置数据格式具体动作与耗时
第一阶段 · 粗筛物理 RAM 内存1-bit 压缩码 / PQ 码在内存中用极速汉明距离或查表扫出 5× top-k 的候选池(如取前 50 条)。耗时几毫秒,内存仅占原来的 1/32。
第二阶段 · 精排廉价 SSD 磁盘 / NVMe原始 float32 / float16 向量仅针对这 50 个候选 ID 进行几十次磁盘随机读(微秒级),计算精确余弦相似度并重新排序,输出最终 top-10。
核心收益这套两阶段架构让 1 亿条 1024 维向量的内存开销从 400 GB 暴跌至 15 GB 左右,单机轻量部署成为现实。当前主流的 DiskANN、Milvus 2.4+、LanceDB 的核心基石均基于此原理。
✦ 本章通关条件
✓
能说出二值量化的压缩倍率,并解释「粗筛 + 磁盘精排」为什么能兼顾极低内存与高召回
查看参考答案
大白话

二值量化把每个数压成正负 1 比特,缩小 32 倍。但尺子变粗了,名次容易乱。办法是先用粗尺子圈出前 50 名候选人(内存粗筛),再从硬盘里把这 50 个人的原始成绩单翻出来精排(磁盘精排),既省下了 90% 内存,又不会找错前 10 名。

专业版

float32 → 1 bit/维实现 32× 压缩。汉明距离受量化误差影响存在排序扰动。通过设置过采样倍数(如 5× 至 10× top-k)建立粗候选集,再基于磁盘常驻的全精度向量完成向量内积精确重排,可将召回率恢复至 95%~99%,将内存瓶颈转化为低成本的局部 I/O 随机读。

承上启下 纯向量搜索已被征服,但现实业务从来没有“裸搜索”!
经过空间剪枝(HNSW)与存储压缩(量化),我们不仅查得飞快,单机还能放下千万级数据。纯几何空间的相似度检索已被彻底拿下。
然而一旦推向真实企业环境,产品经理会当头棒喝:“等等!A 客户绝对不能搜到 B 客户的手册,普通员工绝对不能搜到管理层薪酬表!”
每一个真实的业务请求,都死死绑定着权限与元数据条件(例如 WHERE tenant_id = 'xxx' AND role = 'user')。这种看似简单的“加个 WHERE 过滤”,在向量数据库里却会引发灾难性的“结果缺口”风暴——引出下一章:标量过滤与多租户隔离。
05

过滤与多租户 —— 先过滤还是后过滤

上线前最硬核的业务需求:每个客户只能搜自己的手册,每个部门只能看授权的文档。这在技术上叫「带过滤条件的近邻搜索(Filtered ANN)」。它比传统 SQL 里的 WHERE 条件难得多,是大量团队在生产环境首次翻车的重灾区。

为什么向量过滤比关系数据库难得多?

在传统关系型数据库里,SELECT * FROM docs WHERE tenant_id = 5 ORDER BY id LIMIT 10; 走个 B+ 树索引轻而易举。但向量检索要解决的是:在高维几何空间中,找出既在空间上离我最近、又恰好属于租户 5 的点。 两种看似简单的方式都会踩雷:

致命陷阱 ①后过滤(Post-filtering)的结果缺口

先跑 HNSW 检索出全局 top-10,再剔除不属于租户 5 的数据。致命点:如果租户 5 的数据只占全库的 1%(高选择性),全局 top-10 里平均只有 0.1 条属于他,用户有 99% 的概率会拿到完全空白的结果!

致命陷阱 ②先过滤(Pre-filtering)的图断裂

先用元数据选出租户 5 的全部数据,只在它们内部搜。致命点:对于 HNSW 图索引,如果剔除了 99% 的节点,原本紧密连通的小世界网络会被彻底撕碎成孤岛,贪心搜索根本连不起来,召回率直接归零!

破局解法 ③单阶段迭代遍历(In-search)

在图遍历过程中,遇到非目标租户的节点虽然不加入返回答案,但依然作为寻路跳板(Bridge);如果候选不足,算法自动沿着图继续向下探测,直到凑齐所需条数。

LAB 5.1 · 后过滤的结果缺口模拟器真实计算:1200 个点,k=10,对 150 个查询取平均
观察“凑够 10 条的查询”指标:当租户数很多(剩余比例仅 1%~2% 时),如果过取倍数只有 1~2 倍,几乎所有查询都拿不到 10 条结果!粗略所需过取倍数接近“1 / 剩余比例”。

2026 多租户生产落地的三大架构形态

多租户方案实现方式最佳适用场景注意事项与代价
单集合 + 字段过滤(如迭代扫描)所有租户共用同一个大索引,查询时带 tenant_id = ?。pgvector 0.8+ 提供了 hnsw.iterative_scan,自动迭代探测直到凑满条数。海量中小租户(成千上万家企业),单租户数据量较小。需要数据库支持原生过滤式 ANN,否则选择性过高时查询开销加大。
按租户分区(Partition Key)物理上存储在一个集合内,但底层按租户 ID 划分成独立子分区/子图(如 Milvus 的 Partition Key 机制)。查询直接打向对应分区。租户数量中等(成百上千家),对性能隔离和吞吐要求高。单个集群支持的分区数通常有上限(如几千个),需根据规模规划。
独立集合 / 独立数据库(物理隔离)每个大租户单独建一个 Collection 或独立库实例。超大型大客户、金融/政企客户、合规要求数据物理隔离。租户越多,索引句柄与资源碎片化越严重,集群管理运维成本极高。
✦ 本章通关条件
✓
能解释为什么简单的后过滤会导致严重的结果缺口,并说出工业界两种缓解方案
查看参考答案
大白话

像在全城总成绩榜上抓前 10 名,再看里面有没有你们小区的。你们小区只占全城 1%,这前 10 名里大概率一个都没有。办法:① 每次多抓 100 个人再筛选(过取/迭代扫描);② 或者直接在你们小区内部单独排一个成绩榜(按租户分区)。

专业版

后过滤期望留存条数等于 k·selectivity,高选择性(低 selectivity)场景极易导致有效候选枯竭返回空集。主流解法:① 迭代扫描(Iterative Scan):在图搜索遍历中持续展开候选,直到凑齐 k 条或达到探测上限;② 按租户分区(Partitioning):物理跳过无关数据段,避免跨租户拓扑稀释。

承上启下 系统能查、能存、能按租户隔离,但知识库是“活”的!
到目前为止,检索速度、内存压缩、多租户权限都已妥善解决,整条流水线看似天衣无缝。
然而客服业务是动态的:“昨天业务线更新了退款协议,删除了旧版文档,新增了 500 篇新功能说明,为什么用户还能搜到已被废弃的旧条款?新写进去的手册怎么立刻搜不到?”
向量索引(尤其是 HNSW)建图极其沉重,如果每写入或删除一条数据就原地重构整张图,系统吞吐会直接归零。现代向量数据库是如何借鉴 LSM 思想,一边应对高频写入,一边保证毫秒级查询的?——引出下一章:动态写入、新鲜度与 LSM 分段架构。
06

写入与新鲜度 —— 知识库是活的

知识库每天都在变:工单实时流入、手册频繁修订、过期条款下线作废。向量索引不像平铺数组可以随便塞一条,高维图或聚类结构一旦建好,原地插入或删除代价极其高昂。现代向量数据库借用了 LSM-Tree 的智慧,构建了分段(Segment)生命周期架构。

为什么向量图不能随便“原地插删”?

在已构建完成的密集 HNSW 图上,每当有新向量插入,都需要为其寻找 $M$ 个双向近邻并动态重新连线;若直接删除一个节点,周围邻居的连线可能断裂,形成死胡同。在高并发写入场景下,频繁的原地修改会导致严重的写锁冲突和图拓扑老化,写入性能被死死卡死在每秒几十条。

LSM 风格分段架构的四幕剧

第一幕 · 迎客区增长段(Growing Segment)

新数据写入先进入内存小段。此时完全不建复杂索引,追加写入极快(数万 TPS)。查询时对增长段进行微量内存暴力扫描,与历史段合并,实现写入即刻可查。

第二幕 · 归档区已封存段(Sealed Segment)

当增长段攒够一定规模(如 10 万 ~ 50 万条),系统将其“封存”刷盘,并在后台异步构建高质量的 HNSW 或 IVF 索引。封存后变为只读段,查询享受全速 ANN 检索。

第三幕 · 假死与清理墓碑标记与合并(Compaction)

删除不立刻拆图,只在位图里打上「墓碑(Tombstone)」。搜索时将其过滤。在业务低峰期触发后台合并(Compaction),将多个小段重建为一个大段,此时才真正物理清空死数据、释放空间。

LAB 6.1 · 分段架构模拟器体验完整生命周期:写入、打墓碑、封存建索引、后台 Compaction 合并
观察“查询扇出(段数)”与“相对延迟”:段数越多,查询需要并行的扇出分支越多;增长段没建索引,积压过大也会拖慢整体查询。及时触发封存与合并,是向量数据库维持低延迟的核心运维机制。

生产运维两大避坑指南(必知必会)

常识 ①写入一致性级别(Consistency Levels)

分布式向量库为了高吞吐,通常提供多种一致性级别:Strong(强一致,读写严格等待,最慢);Bounded Staleness(有界时延,如保证 5 秒内可见);Eventually(最终一致,吞吐最高)。客服系统推荐选有界时延,兼顾吞吐与新鲜度。

常识 ②删除后的“存储假占用”陷阱

在生产库中删除了 100 万条废弃向量,发现物理磁盘和内存占用毫无下降,甚至查询还变慢了!——因为墓碑只是标记,仍在占用图节点。批量清理后,必须主动执行一次 Compaction(Milvus/Qdrant)或 VACUUM FULL(Postgres)真正释放空间。

✦ 本章通关条件
✓
能说出「增长段 / 已封存段 / 墓碑 / Compaction 合并」各自的作用,并解释为什么刚删除的向量不立刻释放空间
查看参考答案
大白话

新货先堆在门口临时货架(增长段,没建索引,只能挨个看),攒够一车运进仓库并编好索引大目录(已封存段)。要扔的东西先贴上「作废」便签(墓碑),搜索时装作看不见它,等周末大扫除(Compaction)时才真正拉走扔掉并重新整理货架。

专业版

增长段支持无索引追加写以换取高并发吞吐;封存段为带 ANN 索引的只读数据块。删除通过软删除位图(Tombstone)实现,保证图路由拓扑不被实时破坏。后台 Compaction 异步执行段合并、多版本垃圾回收与索引重构,真正回收内存与 I/O 资源。

终章通关 六幕推演圆满收官:从底层内核迈向商业落地!
从第 01 章的【维度与精度物理形态】→ 第 02、03 章的【IVF 与 HNSW 剪枝原理】→ 第 04 章的【量化与粗筛精排存储压缩】→ 第 05 章的【标量过滤与租户隔离】→ 第 06 章的【LSM 动态分段生命周期】——
你已经完整穿透了现代向量数据库的全部底层黑盒,看清了所有架构取舍背后的第一性原理!
带着这份扎实的内核底气,接下来完成终极测验验收,我们便可踏入生产落地的终局战场——D 篇 · 选型与实战:面对市面上琳琅满目的数据库,你的团队该如何抉择?如何搭出一套兼顾准确率、高并发与性价比的企业级检索系统?
07

终极测验 · 5 题验收

答对 4 题以上,才算把向量库的内核带走。

✦ 本章通关条件
✓
终极测验 5 题答对 ≥ 4(答完自动勾选)
08

参考资料 · References

厂商与博客数据标为「厂商数据 / 观点」。性能数字强烈依赖数据集、硬件与参数,务必在自己的数据上复测。

原理出处

  • Malkov & Yashunin, Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs(HNSW,2016)· arxiv.org/abs/1603.09320
  • Jégou et al., Product Quantization for Nearest Neighbor Search(PQ,2011)
  • Gao & Long, RaBitQ: Quantizing High-Dimensional Vectors with a Theoretical Error Bound(2024)· arxiv.org/abs/2405.12497
  • pgvector 官方 README(HNSW 参数、迭代扫描)· github.com/pgvector/pgvector

2026 年的资料

  • LanceDB’s RaBitQ Quantization for Blazing Fast Vector Search(厂商数据:1024 维约 136 B)· lancedb.com
  • I/O Optimizations for Graph-Based Disk-Resident ANN Search: A Design Space Exploration(2026,论文)· arxiv.org/pdf/2602.21514
  • Vector Databases in 2026: A Systematic Performance Analysis of Indexing Architectures, Quantization Methods, and Production-Scale Retrieval(博客,规模分层对比)· effoma.com
  • Best Vector Databases in 2026: Pricing, Scale Limits, and Architecture Tradeoffs(MarkTechPost,2026-05)· marktechpost.com

本页 IVF 的 k-means、HNSW 构图与搜索、量化实验都是在浏览器里用本页脚本真实运行的简化实现(二维点、合成向量),目的是展示机制与趋势,不代表任何具体产品的性能。

下一页 · D 选型与实战
选型向导 · Adaptive / Agentic / GraphRAG · 成本账 · pgvector 与 Milvus 各搭一套混合检索 · 故障排查决策树
→