数据库基础体系 · 第 60/139 篇。文章以各产品官方稳定版本的公开语义为准;示例会明确引擎、事务与部署边界。
向量索引原理:Flat、HNSW、IVF、PQ 的精度、内存和延迟
向量索引解决的是一个近邻搜索问题:
给定查询向量 ,在数据集
中找出距离 最小的 个向量。
这里至少有三个容易混淆的概念:
- 距离度量:如何计算两个向量的远近,例如 L2、内积、余弦距离。
- 精确搜索:对所有 个向量计算距离,再取真正的 Top-K。
- 近似最近邻搜索(ANN):只访问部分数据或使用压缩表示,以更低延迟换取可能下降的召回率。
Flat、HNSW、IVF 和 PQ 并不是完全同一层次的技术:
- Flat 是不建立近似索引的穷举搜索基线。
- HNSW 是基于图的近似搜索索引。
- IVF 是先分桶、再在少数桶中搜索的倒排索引。
- PQ 是向量压缩和距离近似技术,通常与 IVF 组合成 IVF-PQ。
因此,常见组合包括:
- Flat
- IVF-Flat
- HNSW
- IVF-PQ
其中 IVF-Flat 和 IVF-PQ 的“IVF”负责缩小候选范围,Flat 或 PQ 负责计算候选向量之间的距离。
一、先明确“精度”:距离精确不等于召回精确
1.1 精确 Top-K 的定义
假设使用 L2 距离:
其中:
- 是向量维度;
- 和 是第 维分量;
- 距离越小,向量越相似。
精确搜索必须计算:
然后选出距离最小的 个结果。
如果使用内积:
则通常选择内积最大的结果。余弦相似度为:
如果所有向量都已经归一化,则:
并且:
所以在归一化向量上,最小 L2 距离、最大内积和最大余弦相似度会产生相同的排序。
但如果向量没有归一化,这三种度量不一定等价。将余弦距离改成内积搜索而不归一化,是常见的精度错误。
1.2 召回率的定义
近似索引通常不会直接告诉你“结果错了多少”,而是用精确 Flat 搜索作为基准计算召回率。
对某个查询,设:
- :精确搜索得到的 Top-K 集合;
- :近似索引得到的 Top-K 集合。
则 Recall@K 可以写成:
例如精确结果为:
近似结果为:
那么:
这里的“精度”通常指召回率,而不是浮点距离计算本身是否精确。
- HNSW、IVF-Flat 的向量距离通常仍使用原始向量计算,但候选集合可能不完整。
- IVF-PQ 不仅可能漏掉候选,还可能使用压缩码近似计算距离,因此存在“候选召回误差”和“距离排序误差”两层误差。
二、Flat:精确搜索的基线
2.1 工作方式
Flat 不建立复杂的近似结构。查询到来时,系统依次扫描每个向量,计算距离,再维护 Top-K。
伪代码如下:
result = empty top-k heap
for x in all_vectors:
distance = d(q, x)
result.insert(x, distance)
return result
如果数据有 个向量、每个向量 维,则单次查询的主要计算量约为:
这不是“没有索引”就一定慢,而是它的延迟随数据量近似线性增长。数据量较小时,Flat 反而可能由于没有索引遍历、候选维护和随机访问开销而很快。
2.2 完整数值例子
查询向量为:
候选向量为:
使用平方 L2 距离:
因此精确排序为:
Top-2 是 。Flat 会检查四个向量,因此不会因为索引结构而漏掉 。
2.3 Flat 的内存和延迟
如果使用 32 位浮点数存储向量,原始向量内存大约为:
例如:
- 每个分量 4 字节
则仅原始向量就约为:
这还不包括主键、删除标记、分区结构、页或 segment 元数据,以及数据库本身的缓存和管理开销。
Flat 的特点是:
| 维度 | 特征 |
|---|---|
| 召回率 | 理想情况下为 100%,作为基准 |
| 距离计算 | 对原始向量精确计算 |
| 内存 | 主要是原始向量 |
| 延迟 | 随 线性增长 |
| 构建 | 几乎没有索引构建成本 |
| 适用 | 小数据集、离线评测、精度基线 |
在 pgvector 中,普通的向量排序查询可以作为精确基线:
SELECT id, content, embedding <-> '[0.1,0.2,0.3]'::vector AS distance
FROM documents
ORDER BY embedding <-> '[0.1,0.2,0.3]'::vector
LIMIT 10;
这里 <-> 是 L2 距离操作符。查询是否走索引由 PostgreSQL 优化器决定;没有匹配的近似索引时通常会进行顺序扫描。要做召回率评测,应固定查询、过滤条件和距离度量,把这类结果保存为 ground truth。
三、HNSW:用多层图减少搜索访问量
HNSW 的全称是 Hierarchical Navigable Small World,即分层可导航小世界图。
它的核心思想是:不再扫描所有向量,而是把向量组织成多个图层,通过图上的邻居跳转,逐步接近查询向量。
3.1 图结构
HNSW 中每个向量是一个节点,节点之间有若干邻居边。
通常:
- 最底层包含所有节点;
- 更高层包含较少节点;
- 高层边较长,用于快速跨越数据空间;
- 低层边较密,用于精细搜索。
一次查询大致分为两步:
- 从最高层入口点开始,在稀疏图中贪心向更近的节点移动;
- 到达下一层后,以当前结果为入口继续搜索;
- 在底层使用更大的候选队列搜索,返回 Top-K。
可以把它类比为地图导航:
- 高层是高速公路,快速跨区域;
- 低层是普通道路,精确到达目的地附近。
3.2 HNSW 查询过程
设当前节点为 ,查询向量为 。
如果某个邻居 满足:
则搜索可能移动到 。当当前节点的所有相关邻居都不能继续改善距离时,搜索在这一层停止并下降到下一层。
底层不会只保留一个当前节点,而是维护候选集合。候选集合越大,越有机会探索到真正近邻,但距离计算和队列操作也越多。
因此 HNSW 的典型查询参数包括:
- efSearch:查询时维护的候选规模;
- M:每个节点在图中保留的邻居数量;
- efConstruction:构建图时搜索候选的规模。
通常:
- 增大
efSearch,召回率提高,延迟增加; - 增大
M,图的连通性增强,内存和构建成本增加; - 增大
efConstruction,图质量通常提高,构建时间增加。
这些是常见实现语义,不是所有引擎都使用完全相同的默认值或参数名称。
3.3 HNSW 为什么可能漏结果
HNSW 的图搜索不是对所有节点穷举。一个局部贪心过程可能进入“看起来较近但通往真实近邻的路径不明显”的区域。
构造一个抽象反例:
查询 q
|
入口 s —— 局部节点 a —— 局部节点 b
\
真实近邻 t
如果从 s 到 a 的距离改善明显,但从 a 继续到 b 后,通往 t 的边没有被搜索到,或者候选队列过小,搜索可能在 b 附近结束。即使 t 是全局真正近邻,也可能没有被访问。
增大 efSearch 的作用不是改变向量本身,而是扩大待探索区域,降低这种漏检概率。它不能在有限参数下提供数学意义上的 100% 召回保证。
3.4 HNSW 内存
HNSW 通常保留原始向量,并额外存储图边。
原始向量内存约为:
其中 是每个分量的字节数,float32 时 。
图边内存可粗略估算为:
如果一条边使用 32 位节点编号,且无向关系在实现中按双向边存储,粗略边存储量可能接近:
实际内存会受到以下因素影响:
- 邻居列表的容器开销;
- 多层节点;
- 对齐;
- 删除标记;
- 主键和元数据;
- 引擎是否复制向量或建立额外缓存。
因此不能把这个公式当作精确容量结果,但它能说明一个重要事实:HNSW 的内存通常显著高于只存原始向量的 Flat。
3.5 pgvector 中的 HNSW
pgvector 支持 HNSW 索引。一个示例:
CREATE INDEX documents_embedding_hnsw
ON documents
USING hnsw (embedding vector_l2_ops)
WITH (m = 16, ef_construction = 64);
查询时可以调整搜索候选规模:
BEGIN;
SET LOCAL hnsw.ef_search = 100;
SELECT id, embedding <-> '[0.1,0.2,0.3]'::vector AS distance
FROM documents
ORDER BY embedding <-> '[0.1,0.2,0.3]'::vector
LIMIT 10;
COMMIT;
关键点有两个:
vector_l2_ops必须与查询操作符匹配。使用内积或余弦距离时,应建立对应的操作类。ef_search是查询级别的近似搜索参数。用SET LOCAL可以把影响限制在当前事务,而不是永久改变整个会话或实例配置。
在 PostgreSQL 中,索引仍然参与普通事务语义。插入、更新、删除与事务提交、回滚相关;但索引构建本身仍然需要考虑锁、资源和构建失败后的恢复。HNSW 不是一个脱离数据库事务系统独立运行的缓存。
四、IVF:先分桶,再搜索候选桶
IVF 的全称是 Inverted File Index,即倒排文件索引。
它先用聚类中心把向量空间划分成若干个桶,再根据查询向量找到最相关的少数桶,只在这些桶里搜索。
4.1 建立 IVF 的过程
设聚类中心为:
其中 是桶数量,通常称为 nlist 或类似名称。
对每个向量 ,分配到距离最近的中心:
于是每个桶保存一组向量:
查询时,先计算查询向量与所有中心的距离,找到最近的 个桶:
然后只扫描这些桶中的向量。这里的 通常称为 nprobe 或 probes。
nlist决定数据被分成多少桶;nprobe决定一次查询访问多少桶。
4.2 IVF 的召回反例
假设真实最近邻 被分配到了桶 2,但查询 的最近中心是桶 1:
查询 q —— 中心 c1
\
真实近邻 x* 位于 list_2
如果 nprobe=1,只搜索桶 1,那么 根本不会参与最终排序。即使桶 1 内的距离计算完全精确,结果仍然可能错误。
这说明 IVF-Flat 的误差主要来自:
候选桶没有覆盖真实近邻。
而不是来自桶内的距离计算。
增大 nprobe 会让更多桶参与搜索:
因此召回率通常提高,但延迟和 CPU 消耗也会增加。若 nprobe=nlist,理论上会搜索所有桶,此时 IVF-Flat 的候选范围接近 Flat;但它仍可能承担中心查找和倒排结构的额外开销,因此不一定比直接 Flat 更快。
4.3 IVF 的内存和构建边界
IVF 需要保存:
- 聚类中心;
- 每个向量所属的桶;
- 倒排列表;
- 向量本身,若使用 IVF-Flat;
- 或压缩码,若使用 IVF-PQ。
中心内存约为:
相对于 ,当 时通常很小。真正影响运行时的是:
- 桶是否均衡;
- 查询要探测多少桶;
- 桶内向量是否连续;
- 候选是否需要从磁盘或远程存储加载。
聚类中心不是凭空产生的。IVF 建立前通常需要训练或聚类。训练样本不能代表真实数据分布时,桶边界质量会下降。
例如,历史数据主要来自英语文本,但新数据主要来自代码和多语言文本,继续沿用旧中心可能造成:
- 新数据集中落入少数桶;
- 某些桶过大;
- 查询对应的中心不稳定;
nprobe相同但实际扫描量显著变化。
因此 IVF 的“索引创建成功”不等于聚类质量足够好。
4.4 pgvector 中的 IVFFlat
pgvector 支持 IVFFlat。示例:
CREATE INDEX documents_embedding_ivfflat
ON documents
USING ivfflat (embedding vector_l2_ops)
WITH (lists = 100);
查询时可以设置探测桶数量:
BEGIN;
SET LOCAL ivfflat.probes = 10;
SELECT id, embedding <-> '[0.1,0.2,0.3]'::vector AS distance
FROM documents
ORDER BY embedding <-> '[0.1,0.2,0.3]'::vector
LIMIT 10;
COMMIT;
lists 与查询时的 probes 共同决定搜索行为。建立 IVFFlat 时,训练数据应尽量包含具有代表性的数据。对一个刚创建但数据量很少的表建立 IVF,然后大量写入分布不同的数据,索引质量可能不理想。
五、PQ:把向量变成短码
PQ 的全称是 Product Quantization,即乘积量化。
它的目标不是减少候选桶数量,而是用更短的编码近似表示向量,从而减少内存和距离计算成本。
5.1 分段量化
设原始向量维度为 ,将其分成 个子向量:
每个子向量维度约为:
对第 个子空间训练一个码本:
其中 , 是每个子空间使用的比特数。
编码时,对每个子向量选择最近的码字:
整个向量只保存 个码字编号。
例如:
- 每个子空间 bit
则一个向量的 PQ 编码大小为:
原始 float32 向量大小为:
编码部分理论上缩小到四分之一。实际系统还需要保存码本、主键、倒排结构和管理元数据。
5.2 PQ 的距离近似
以 L2 距离为例:
PQ 将 替换为对应码字 :
查询时,可以为每个子空间预先计算查询子向量到所有码字的距离表,然后通过查表快速累加。
误差来自量化残差:
如果残差较大,近似距离就可能明显偏离真实距离。
5.3 一个排序反例
假设两个候选的真实距离为:
如果 PQ 量化后:
则压缩距离会把 排在 前面。此时即使两个候选都已经进入搜索范围,PQ 仍然可能改变最终 Top-K 排序。
因此 PQ 的误差有两层:
- IVF 可能没有把真实近邻所在的桶加入候选;
- PQ 可能把候选向量的距离估计错,导致排序改变。
在某些实现中,会对 PQ 找到的候选再使用原始向量重排,以减少第二种误差。这会增加原始向量访问和距离计算成本,具体是否支持、如何配置,应以对应引擎版本的文档为准。
六、IVF-PQ:用分桶和压缩同时降低成本
IVF-PQ 将两种机制串联起来:
- 使用 IVF 找到
nprobe个候选桶; - 使用 PQ 码快速计算桶内向量的近似距离;
- 返回近似 Top-K,或者对部分候选进行原始向量重排。
其查询成本可以粗略理解为:
其中:
- 是桶数量,查询中心阶段需要比较的中心数;
- 是被探测桶中的候选向量数量;
- 是 PQ 子空间数量。
这不是严格的端到端复杂度公式,因为缓存、SIMD、磁盘访问、并行度和数据布局都会影响实际性能,但它体现了 PQ 的主要收益:候选距离计算不再完整读取 维浮点向量。
PQ 的主要代价是:
- 训练码本需要 CPU 和样本;
- 码本不适合当前数据分布时,量化误差升高;
m、每段 bit 数、是否残差量化会影响质量;- 重排会重新引入原始向量读取;
- 更新数据后,原有码本是否仍然适合,需要重新评估。
在 Milvus 的索引体系中,FLAT、IVF_FLAT、IVF_PQ、HNSW 等是不同索引类型;具体参数名称通常包括 nlist、nprobe、M、ef、PQ 的子空间数量和每段位数等。不同 Milvus 稳定版本、索引类型和部署模式可能有参数约束,不能把某个版本示例中的参数直接套用于所有索引。
七、四种方式的内存与延迟对比
设:
- :向量数量;
- :维度;
- :每个浮点分量字节数;
- :IVF 桶数;
- :查询探测桶数;
- :HNSW 邻居规模;
- :PQ 子空间数。
7.1 内存模型
| 索引 | 主要内存组成 | 粗略特征 |
|---|---|---|
| Flat | 原始向量 | |
| HNSW | 原始向量 + 图边 | |
| IVF-Flat | 原始向量 + 中心 + 倒排列表 | 列表开销 |
| IVF-PQ | PQ 编码 + 码本 + 倒排列表 | 码本和列表开销 |
PQ 表达式中的 应改为每个编码位数对应的字节换算;例如每个子空间 8 bit 时,每个向量编码占 字节。
7.2 延迟模型
| 索引 | 主要延迟来源 |
|---|---|
| Flat | 扫描全部向量并计算完整距离 |
| HNSW | 图遍历、候选队列、随机访问 |
| IVF-Flat | 计算中心距离、读取探测桶、对候选计算完整距离 |
| IVF-PQ | 计算中心距离、读取压缩码、查表和累加,可能还要重排 |
延迟不是只由算法名字决定的。例如:
- HNSW 访问节点通常不连续,CPU 缓存不友好;
- IVF-Flat 候选可能连续存储,适合批量计算;
- IVF-PQ 计算少,但如果重排阶段需要随机读取大量原始向量,收益会下降;
- Flat 可以很好地利用 SIMD 和顺序内存带宽,在中小数据集上未必输给复杂索引。
因此“复杂度更低”不能直接等价为“线上 P99 更低”。
八、如何选择参数,而不是凭经验猜数值
8.1 HNSW 参数变化
以 pgvector 的 HNSW 参数为例:
CREATE INDEX items_embedding_hnsw
ON items
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
查询阶段:
BEGIN;
SET LOCAL hnsw.ef_search = 80;
SELECT id, 1 - (embedding <=> '[0.1,0.2,0.3]'::vector) AS cosine_similarity
FROM items
ORDER BY embedding <=> '[0.1,0.2,0.3]'::vector
LIMIT 20;
COMMIT;
这里 <=> 是余弦距离,1 - distance 在该度量下可作为余弦相似度表达。前提是查询和数据使用同一度量语义,且不能把距离和相似度的排序方向弄反。
调参时应观察:
- Recall@K;
- 平均延迟和 P95/P99;
- CPU;
- 内存;
- 构建时间;
- 写入吞吐。
只提高 ef_search 而不测量,可能把召回率提升换成不可接受的尾延迟。
8.2 IVF 参数变化
IVF 同时存在“训练参数”和“查询参数”:
nlist:分桶数量,影响桶平均大小;nprobe:查询访问的桶数量,直接影响候选量。
如果每个桶平均有 个向量,那么粗略候选数约为:
但真实数据通常不均匀,因此实际候选数还取决于桶大小分布。
当 太小:
- 每个桶很大;
nprobe即使较小也会扫描大量候选;- IVF 的缩小效果有限。
当 太大:
- 中心训练和查询开销增加;
- 桶可能过小;
- 数据分布变化时,中心质量更敏感;
- 查询探测比例不变时,候选数量可能下降,但召回风险上升。
应该用代表性数据集做网格测试,而不是只根据向量总数套用固定比例。
九、过滤条件会改变索引的有效召回
向量搜索经常不是全表 Top-K,而是:
SELECT id
FROM documents
WHERE tenant_id = 42
ORDER BY embedding <-> $1
LIMIT 10;
这引入了一个额外问题:近似索引找到的候选,可能大部分不满足过滤条件。
假设系统先取得 10 个近似候选,再应用租户过滤:
近似候选:a,b,c,d,e,f,g,h,i,j
满足 tenant_id=42:只有 c
最终只能返回一个结果,即使过滤后的数据集中实际存在很多近邻。
增加预取候选数有时可以缓解:
先取 100 个候选
过滤后剩余 12 个
再返回前 10 个
但这会增加延迟,而且不能保证过滤选择性极低时仍然足够。
因此评测向量索引时,至少要分别测试:
- 不带过滤的 Recall@K;
- 高选择性过滤;
- 低选择性过滤;
- 多租户或分区场景;
- 过滤字段发生更新或删除后的行为。
PostgreSQL 和 Milvus 对过滤、分区、segment、索引扫描的执行路径不同。不能把一个引擎的“先向量搜索后过滤”假设直接套到另一个引擎上。应通过 EXPLAIN、查询执行统计或引擎提供的搜索统计确认实际路径。
十、数据写入、索引构建和故障边界
10.1 PostgreSQL/pgvector
pgvector 作为 PostgreSQL 扩展,向量列、表、索引和事务都处在 PostgreSQL 的事务模型中。
典型流程:
CREATE TABLE documents (
id bigint PRIMARY KEY,
tenant_id bigint NOT NULL,
content text NOT NULL,
embedding vector(3) NOT NULL
);
INSERT INTO documents(id, tenant_id, content, embedding)
VALUES
(1, 42, 'first', '[0.1,0.2,0.3]'),
(2, 42, 'second', '[0.2,0.1,0.4]');
随后建立索引:
CREATE INDEX documents_embedding_hnsw
ON documents
USING hnsw (embedding vector_l2_ops);
需要注意:
- 建索引前已有数据需要被纳入构建;
- 建索引期间会消耗 CPU、内存和 I/O;
- 写入和更新会带来索引维护成本;
- 大规模构建应结合 PostgreSQL 的锁、并发建索引、备份和恢复策略评估;
- 备份不仅要考虑表数据,也要验证恢复后索引是否存在、查询计划是否符合预期。
10.2 Milvus
Milvus 通常以 collection、segment 和索引构建任务组织数据。数据写入、flush、索引构建、加载和查询是相互关联但不完全相同的阶段。
一个典型生命周期是:
创建 collection
↓
插入向量和标量字段
↓
flush,使数据形成可持久化 segment
↓
为向量字段创建索引
↓
load collection 或相关 partition
↓
执行 search
索引创建完成不代表数据自动处于可查询的内存状态;部署模式、segment 状态和 load 状态会影响查询是否能执行以及资源使用。
故障诊断时应区分:
- 数据是否已经 flush;
- 索引任务是否成功;
- collection 或 partition 是否已 load;
- 查询字段维度和度量是否匹配;
- 标量过滤字段是否存在并使用正确类型;
- 新写入数据是否仍处于待整理或待索引状态;
- 节点重启后索引文件和数据是否能够重新加载。
Milvus 的具体 API 和索引参数会随稳定版本变化,生产代码应锁定客户端与服务端兼容版本,并对创建索引、加载、搜索失败实现显式错误处理,而不是只检查请求是否发出。
十一、如何建立可复现的评测
一个可靠的评测必须先固定实验边界。
11.1 固定数据和度量
至少固定:
- 向量维度;
- 数据集版本;
- 查询集;
- Top-K;
- L2、内积或余弦距离;
- 是否归一化;
- 是否带标量过滤;
- 单机还是分布式部署;
- 冷缓存还是热缓存;
- 并发数。
11.2 用 Flat 生成 ground truth
以 pgvector 为例,可以先执行不依赖 ANN 索引的查询,保存每个查询的精确 Top-K。之后再分别运行 HNSW、IVFFlat,并计算:
不要用 HNSW 的结果去验证 HNSW,也不要用某一组 IVF 参数生成另一组参数的“真值”。
11.3 记录三个维度
每组参数至少记录:
索引构建时间
索引和数据占用内存/磁盘
Recall@K
P50/P95/P99 延迟
查询吞吐
写入或更新吞吐
尤其要记录 P99。某组参数可能平均延迟很好,但在大桶、冷缓存或高并发下出现严重尾延迟。
十二、常见误解和失败表现
误解一:HNSW 一定比 Flat 快
错误。数据量小、查询并发低、数据全部在缓存中时,Flat 可能更快。HNSW 只有在减少的距离计算量足以抵消图遍历开销时才有优势。
误解二:IVF-Flat 是精确搜索
错误。Flat 只表示桶内使用原始向量计算距离。IVF 仍然可能因为只探测部分桶而漏掉真实近邻。
误解三:PQ 只是把 float32 改成 int8
错误。PQ 是按子空间训练码本,并用码字编号表示向量。它不同于简单的标量量化。标量量化把每个分量独立映射,PQ 则利用子空间中的联合结构。
误解四:增加索引内存一定提高召回率
不一定。
- HNSW 增加
M通常有利于图连通性; - IVF 增加
nlist可能减少单桶大小,但如果nprobe不同步调整,召回率可能下降; - PQ 使用更高码率通常降低量化误差,但码本、训练数据和重排策略同样重要。
误解五:返回了 K 条结果就说明召回率足够
错误。系统可能用次优结果填满 K 条。必须与精确 ground truth 比较,才能知道真正漏掉了多少近邻。
误解六:建立索引后所有查询都会使用它
错误。数据库优化器可能认为顺序扫描更便宜,或者查询表达式、操作符、操作类不匹配。应检查执行计划或引擎查询统计,而不是仅凭“索引已创建”判断。
十三、最终取舍
可以用下面的原则理解四种方式:
- Flat:用计算时间换取确定的精确结果,适合基准、小规模数据和高精度校验。
- HNSW:用额外内存和构建时间换取较低查询延迟,适合需要在线低延迟且内存充足的场景。
- IVF-Flat:用聚类和候选桶缩小搜索范围,保留原始向量距离计算,参数解释相对直接。
- PQ:用量化误差换取更低内存和更少数据读取,适合规模较大、能够接受近似结果或采用重排的场景。
- IVF-PQ:同时利用分桶和压缩,通常在规模、成本和召回之间取得平衡,但参数和训练数据更加敏感。
工程上不应先问“哪个索引最好”,而应先确定:
然后以 Flat 结果作为精度基线,逐步增加 HNSW 的 efSearch、IVF 的 nprobe,或调整 PQ 的编码参数,测量真实的 Recall@K、内存和尾延迟。索引选择的本质,是在“访问多少数据”“以什么表示计算距离”和“是否允许漏掉或误排结果”之间做出可验证的取舍。
系列导航与关联阅读
- 系列入口:数据库完整学习路线:从关系模型、事务索引到分布式与向量检索
- 上一篇:向量数据库基础:Embedding、距离度量、召回、过滤与一致性
- 下一篇:pgvector 实战:PostgreSQL 向量类型、HNSW、IVFFlat 与混合查询
- 延伸:向量数据库生产运维:摄取、版本、评测、备份、权限和成本
官方资料
本文依据数据库官方文档重新梳理;正文、示例与生产检查清单由 WR BLOG 编写。

评论
0 条讨论