Chapter 05
自测辨析:把四章合成一张可调用的网
前四章分别建立了概念(01)、索引原理(02)、生产工程(03)、选型与前沿(04)。这一章不引入新知识,只做一件事:用三层梯度的题目,逼你把这些散点连成一张面试时能即时调用的网。
这一章怎么用
- 三层梯度:概念层(回忆 01)→ 原理层(理解 02–03)→ 应用判别层(跨章迁移)。越往上越接近真实面试。
- 所有答案集中在页面最底部的一个折叠块里。做完一整层再展开对照,别逐题瞄答案。
- 应用判别层是重心——5 个场景,每个都标注了它考的是哪几章。能讲清这 5 题,就过了向量数据库这一关。
纪律:先合上其余五页,把答案写在纸上或编辑器里,写完再展开底部答案。直接看答案,等于把这一章当成第六遍泛读——流畅感不是掌握。
▸题目的三层梯度
这张图说明每一层考什么、对应哪几章、为什么越往上越难。做题前先认准自己卡在哪一层。
1概念层 · 对应 01 章
这一层只考定义与基本区分。能脱口而出,才有资格往上爬。
- embedding 把什么变成了什么?为什么这一步让「搜索」从字符串匹配变成了「求最近邻」?提示:01 章 概念 1
- cosine 与 dot product 在什么条件下排名完全等价?为什么这个条件成立时大规模检索更偏好 dot product?提示:01 章 概念 2
- recall@k 衡量什么?一个精确 KNN(暴力)的 recall@k 等于多少?提示:01 章 概念 3
- FAISS 是「库」而非「数据库」。列出 3 个 Milvus 有、而 FAISS 没有的能力。提示:01 章 概念 4
- 「index」这个词在 Pinecone 与 Qdrant 两种语境下分别指什么?为什么这是个面试地雷?提示:01 章 概念 6
2原理层 · 对应 02–03 章
这一层考机制:不是「是什么」,而是「为什么这样、代价在哪」。
- 为什么暴力 KNN 在亿级数据上不可行?维度灾难具体如何让 KD-tree 这类划分树退化?提示:02 章 §0
- HNSW 的多层图里,顶层与底层各负责什么?把 ef_search 调大,recall 和延迟会怎么变?提示:02 章 §2
- 为什么纯 PQ 几乎从不单独使用?binary quantization 把 32× 压缩后的 recall 拉回 ~0.98,靠的是哪一步?提示:02 章 §3
- DiskANN 的 α>1 参数为什么能减少查询时的 SSD 随机读次数?这里的瓶颈为什么是 IO 次数而不是算力?提示:02 章 §4
- 带 metadata 过滤的检索里,post-filter 为什么会返回少于 k 个结果?pre-filter 又为什么在大集合上反而把召回打下来?提示:03 章 §1
- hybrid 检索为什么在 2026 年是生产标配?纯 dense 向量检索在哪一类查询上会「静默失败」?提示:03 章 §2
- 为什么向量库的删除量累积到 10–20% 就需要 compaction/rebuild?这和 HNSW 的删除机制有什么关系?提示:03 章 §4
3应用判别层 · 跨 01–04 章
这一层是重心,也是面试现场的真实形态:给一个场景,逼你在多章的方案之间判别。每题先标注它考的是哪几章——先别看答案,自己把决策链讲出来。
- 场景 A(三角权衡 · 02 章):1000 万条 768 维向量,延迟预算 20ms,内存预算只有 8GB(原始数据约 30GB)。在 HNSW、IVFPQ、DiskANN 之间选哪个?为什么内存预算是这里的决定性约束?
- 场景 B(选型 + 一致性 · 04 + 03 章):团队已经在跑 Postgres,向量规模 800 万,检索结果需要与订单表做 JOIN,最终一致可接受。选 pgvector、Milvus 还是 Pinecone?为什么这里不上 Pinecone?
-
场景 C(过滤策略 · 03 章):多租户 SaaS,每个查询都必须按
tenant_id过滤,租户基数从 10 到 10 万不等。post-filter、pre-filter、filtered-HNSW 三种策略,怎么按租户基数分流使用? - 场景 D(hybrid · 03 + 01 章):一个面向工程师的文档检索,30% 查询是精确的错误码 / 函数名匹配,70% 是语义提问。纯向量检索够吗?如果不够,加什么、用什么把两路结果合一?
- 场景 E(演进 + scale · 04 + 02 章):项目现在 500 万向量,预计两年内涨到 5 亿,且 30% 查询是精确 SKU 匹配。今天选什么、迁移路径怎么提前留出来?
合上全部教程,在纸上或 Excalidraw 里画出向量数据库的主干——只画 6 个节点:文本 → 向量 → 相似度 → ANN 索引 → 向量数据库 → 选型,并标出它们之间边上的那句话。
画完回到 起点页 · 概念地图(图 0.1) 对照,回答两个问题:① 你画的图里,「recall × 延迟 × 内存 三角」挂在哪个节点上?② + 持久化 / CRUD / 过滤 那条边,把哪两个概念分开了(也就是「库」和「数据库」的分界)?画得出、答得上,这张网才真的在你脑子里。
面试模拟:90 秒讲清「一次带过滤的语义检索,从 query 到结果发生了什么」
不看教程,用一段连贯的话讲完整条链路:query 文本 → embedding → 选定相似度度量 → 进入哪种索引 → 如何在三角权衡里取舍 → 带 tenant_id 过滤时走哪种过滤策略 → 是否需要 hybrid 与 rerank → 结果。每一环都要点到它在哪一章、为什么这么选。讲不顺的环,就是你 schema 上的断点——回那一章补。
提示(卡住再展开)
按 01→02→03 的顺序串:度量来自 01;「进哪种索引 + 三角取舍」来自 02;「过滤策略 + hybrid + rerank」来自 03。选型(04)只在「这套部署在 pgvector 还是 Qdrant 上」时出现。能把这条链不回看讲完,等于把图 0.1 的每条边都激活了一遍。
▸答案
下面是全部三层的参考答案。做完整层再展开——尤其是应用判别层,先把自己的决策链写完。
展开全部答案(先做完再点)
概念层
- embedding 把文本 / 图像变成定长浮点数组(向量),让语义相似的对象在高维空间里坐标相近。于是「找意思相近的内容」等价于「在这个空间里找离 query 向量最近的点」——搜索从字符串匹配变成几何上的最近邻问题。
- 当所有向量都做了 L2 归一化(单位化)时,cosine 与 dot product 排名完全等价:cosine = dot / (‖a‖‖b‖),范数都为 1 时分母恒为 1。此时 dot product 省掉了除以范数的计算,大规模检索更快——所以很多系统在归一化后直接用内积。
- recall@k 衡量近似结果命中真实 top-k 的比例(命中数 / k),是 ANN 精度的核心指标。精确 KNN(暴力)总是返回真正的 top-k,所以 recall@k = 1.0,它是衡量一切 ANN 索引的 ground truth。
- 三选其三即可:① 持久化 / 崩溃恢复(durability);② 增量 CRUD(FAISS 索引近乎不可变,加删一条要重建);③ metadata 过滤;④ 分布式 sharding / replication;⑤ 网络服务 API(HTTP/gRPC,而非进程内 FFI)。FAISS 只提供内存里的索引算法。
- Pinecone 的
index是顶层容器(≈ 别家的 collection / 一张表);Qdrant 等语境里index指底层的 ANN 结构(HNSW / IVF)。同一个词指着两个不同抽象层,面试时不澄清就会答岔——这是术语地雷。
原理层
- 暴力 KNN 每次查询要算 N 个向量的距离、每次 d 维,复杂度 O(N·d),亿级 × 高维要扫 TB 级数据。维度灾难下,高维空间里所有点对距离趋同(最近 / 最远距离比 → 1),KD-tree 的「按某一维切分」几乎无法排除任何分支,回溯到接近遍历全部点,退化成近似线性扫描——这正是图 / 量化方法胜出、划分树失败的根因。
- 顶层最稀疏、只有长程边,负责「大跨步」快速逼近目标区域;底层最稠密、含全部点,负责「精定位」。ef_search 是查询期动态候选堆的大小:调大 → 探索更多候选 → recall↑、延迟↑。它是上线后换 recall ↔ 延迟最直接的旋钮。
- 纯 PQ 把向量压成几十字节的码字,recall 可能掉到 ~50%,单用精度不够,所以几乎总是配 IVF(先粗筛 cell)或图结构兜底。binary quantization 的 ~0.98 recall 靠的是 rescore:先用 1-bit 码做 oversampling 召回一批候选,再用原始 float32 向量对候选重排。量化方法的「实际 recall」几乎都挂在 rescore 这一步。
- DiskANN 的瓶颈是从 SSD 取数据的随机读次数(每跳一个图节点就要读一次盘),不是 CPU 算力。α>1 放松了 RobustPrune 的剪枝规则,故意保留更多长程边,使图直径变小 → beam search 用更少跳数就能收敛 → 更少 SSD 随机读。把图结构的几何性质直接翻译成了 IO 经济学。
- post-filter 先 ANN 取 m 个再筛 metadata,命中过滤条件的可能不足 k 个,结果「缺斤少两」(pgvector 实测 LIMIT 15 只回 11 行、还漏掉 23 个更近的命中)。pre-filter 先按 metadata 删节点再搜,会切断 HNSW 图的连通性,使搜索走不到本该可达的近邻,召回崩塌,或退化成近线性暴力扫。两者都不是「稳妥」选项——这是过滤难题的核心反直觉点。
- 纯 dense 向量会把精确 token(错误码、SKU、函数名、ID)「抹平」成语义邻近,返回意思接近但不含原词的文档,长尾标识符查询静默失败(不报错、结果就是错)。hybrid 用稀疏(BM25/SPLADE)补上精确匹配,与 dense 的失败模式互补,再用 RRF 融合 + rerank 收口,所以成了标配。
- 图索引硬删困难(删点会断连通),普遍用 tombstone 软删——被删点仍占内存、仍可能出现在遍历路径里。删改累积后召回逐步劣化,甚至产生 unreachable points。业界经验阈值是删除量到 10–20% 就 compaction / rebuild,把墓碑真正清掉、重建图。
应用判别层
- 场景 A → DiskANN(或 IVFPQ)。内存预算 8GB < 原始数据 30GB,HNSW 要把全精度向量 + 图驻 RAM(1.2–2× 原始 ≈ 36–60GB),直接出局。DiskANN 让图 + 全精度向量躺 SSD、内存只放压缩码,正好吃这个「内存远小于数据」的场景,且能守住 20ms 量级。IVFPQ 是次选(cell 内存压缩码,内存也低,但 recall 比 DiskANN 略逊)。决定性约束就是内存——三角里你被迫牺牲的是「内存」这个角,于是选把数据放盘的索引。
- 场景 B → pgvector。800 万向量在 pgvector 的舒适区(<10–50M),且「与订单表 JOIN + 最终一致可接受」恰好是它的真正卖点:向量和业务数据同库、同事务写入,无孤儿向量、无跨服务同步。上 Pinecone 反而要多一个服务、把订单数据和向量拆到两套系统、JOIN 变成应用层拼接——为「用不上的规模」付了运维与一致性的代价。规模没到亿级,「你可能不需要专用向量库」。
- 场景 C → 按基数分流。高基数过滤(
tenant_id命中率极低,如 10 万租户里选 1 个):post-filter 会几乎筛空,应走 filtered-HNSW(遍历图时跳过不匹配点,召回不掉)。低基数过滤(如只有 10 个租户、每个占 1/10 数据):命中率高,pre-filter 或 filtered-HNSW 回退全扫都可接受,甚至 post-filter + 适当 oversample 也能凑够 k。核心是:过滤选择性(命中率)决定策略,而不是「哪个策略永远最好」。 - 场景 D → 不够,上 hybrid。30% 的精确错误码 / 函数名查询正是 dense 的静默失败区(会把
NPE-0042抹成语义邻近)。加一路稀疏检索(BM25/SPLADE)做精确 token 匹配,与 dense 并行召回,用 RRF 按排名融合两路结果,必要时再加 rerank(cross-encoder)收口。这题同时用到 03 章的 hybrid 和 01 章的稀疏向量概念。 - 场景 E → 今天可上 pgvector 或 Qdrant,但按「会迁移」来设计。500 万现在哪个都行,但两年到 5 亿会冲破 pgvector 的舒适区,终点更可能是 Milvus/Zilliz(十亿级 + 分布式)。迁移路径预留:① 把 embedding 维度、相似度度量、metadata schema 固定下来(换库不用 re-embed);② 检索逻辑抽一层接口,别让业务直接耦合某个库的 API;③ 那 30% 精确 SKU 匹配从第一天就上 hybrid(稀疏路),免得迁移时才发现 dense 漏召回。先选能快速交付的,但把「不可逆的决策」(维度、度量、是否 hybrid)今天就定对。