跳到主要内容

存到哪儿、搜得多快

这一章讲三件事: 这堆数该放在哪、放进去之后一次查要多久、 以及加速的那个东西是拿什么换来的

它在全书链条上的位置:第 02 章那条走查的第 3 步和第 5 步。 「连块带数存进库」和「在库里比出最像的几串」——这两步归这一章。

1. 这一章讲什么(以及先把两个说法分开)

三句话:

  1. 「挑一个向量数据库」——就是专门存那些数、并且能按方向飞快找出最近几串的那种库—— 听着像个选型题,其实它是两个连着的问题:这堆数该跟谁待在一起、以及一次查要等多久;
  2. 第一个问题有一条四步决策路径,而书说多数团队犯的错是照榜单选,不是照工作流选;
  3. 第二个问题有一组书里少见的实测数——而加速换来的那点速度,是拿准确度换的。

先把两个天天撞见、其实不是一回事的说法分开

书专门用一段做了这个澄清,值得照搬1:

说法它是什么
相似度搜索一个技术操作:在一堆向量里,找出和给定那一串靠得最近的几串
语义搜索一个面向用户的能力:按意思搜,而不是按精确的关键词搜

关系是:语义搜索是用相似度搜索实现的。 前者是你对用户承诺的效果,后者是你在库里执行的那个动作。

2. 顶层全景:两个问题,两组答案

问题一:这堆数该跟谁待在一起?
├─ 只在离线流水线里用一下就丢 → 内存里的索引就够
├─ 要和你的业务数据、用户、权限待在一起 → 用你已经在运维的那个数据库
├─ 会长到几千万条、还要过滤和权限 → 专门的向量数据库
└─ 小团队、要求配置最少 → 装上就能用的那种

问题二:一次查要等多久?
20 万条,一条一条全算一遍 → 85.6 毫秒
先造一份册子(建索引) → 13.9 毫秒 快约六倍
↑ 但这份册子有可能漏掉真正最近的那一条

图说:上半张图是第 3 到 6 节,下半张是第 7 到 9 节。
两个问题各自独立 —— 你可以在任何一个库上建索引,也可以任何一个都不建。

3. 四步决策路径

书没有给「哪个最好」,它给了一条一路问下去的路径2:

第 1 步 这次的相似度搜索,是不是一个活的线上应用的一部分?
├─ 不是(只在预处理、实验、离线流水线里用)
│ → 用一个纯内存的索引库;本地做原型就用那种进程内嵌的
└─ 是 → 第 2 步

第 2 步 这些数需不需要和你的业务数据、用户、文档、权限待在一起?
├─ 要 → 用你已经在运维的那个数据库(比如加了向量扩展的关系数据库)
└─ 不要 → 第 3 步

第 3 步 会不会长到几百万甚至几千万条?需不需要过滤、权限、可预测的延迟?
├─ 要 → 自建就选专门的向量数据库,不想运维就选全托管的
└─ 不要 → 那种进程内嵌的可能还够

第 4 步 拿四个现实问题再筛一遍(见下)

图说:注意第 2 步。它一旦答"要",后面两步就不必问了 ——
而这正是第 04 章第 9 节埋下的那条伏笔。

第 4 步那四个现实问题3:

问题答「是」就倾向于
数据能不能发给第三方的托管云服务?托管的向量数据库,或者云托管的关系数据库
你是不是已经在运维某个数据库了?就用它加个向量扩展
需不需要关键词搜索和向量搜索一起用?那些本来就是搜索引擎出身的
小团队、希望配置最少?装上就能用的那种,或者全托管的

最该记住的一句:照工作流选,不照榜单选

书自己下的判断4:

「许多团队犯的错是照着基准选,而不是照着工作流选。 几千个块的 RAG 原型不需要分布式的向量数据库;服务大量用户的生产助手才需要。」

这句话和第 03 章第 10 节那条「榜单只能当筛子」是同一个形状。

4. 它们其实是四类东西,而不是一堆同类产品

这是这一节要说破的:「向量数据库」这个词底下装着四类不同的东西5:

它是什么典型场景
向量索引库一个装进你程序里的库,数据在内存里,程序一停就没了离线批处理、一次性分析
进程内嵌的存储上一类加上轻量的落盘和基本的标注过滤原型、笔记本
带向量扩展的数据库你已经在用的关系数据库,装个扩展就多了向量能力向量要和业务数据待在一起
专门的向量引擎为大规模而生,过滤能力强,但要多养一套运维几千万条以上、要权限和可预测延迟

书还顺手解释了一件事:为什么那些搜文本出身的引擎在这个领域也很流行6—— 因为「搜语义文本块的检索器本来就像一个专门的搜索引擎」。

三级阶梯:每一级多给了什么

书把最常见的三个选项排成一条阶梯,每一级只比上一级多一点东西7:

第 1 级 内存里的向量索引
可以序列化写到磁盘,但没有数据库级的持久化、标注、并发控制
↓ 加上
第 2 级 轻量的落盘 + 基本的标注过滤
↓ 加上
第 3 级 完整的查询语句、事务、生产级的权限控制
代价:你要管一个数据库

书给的对应关系:
批处理作业和离线索引 → 第 1 级
需要简单持久化的原型 → 第 2 级
生产系统 → 第 3 级

图说:"事务"在这里就是"一组操作要么全部生效、要么全部不生效"。

每一级的反面判据也很具体:

  • 第 1 级不该用在: 需要跨运行保留数据、需要标注过滤、需要按用户区分权限的时候8;
  • 第 2 级不该用在: 数据超过几十万条向量、需要按角色控制权限、 需要和应用数据做关联查询、或者规模上要求查询延迟低于 10 毫秒的时候9;
  • 第 3 级不该用在: 要在几亿到几十亿条向量上做个位数毫秒的延迟; 或者纯向量搜索、完全没有标注过滤(那时候第 1 级更快)10

5. 换库不贵 —— 因为贵的那部分不用重做

这是这一章最该带走的一条,而且它是全书「先简后繁」最硬的一处依据11:

「如果你先用一个简单的向量索引库、后来需要完整的数据库,迁移通常不难。 你必须重建索引,但不需要重新生成那些数——而生成那些数才是贵的那部分。」

换一个存放的库:
├─ 那些数(每块 1 536 个) → 原样搬过去,一个都不用重算 ✓ 贵的这部分免了
└─ 索引 → 重建一次 ✗ 但这个便宜

换一个换算模型(第 02 章第 6 节):
└─ 全部重算 → 贵的那部分躲不掉

图说:两件事看着都叫"换",代价差了一个数量级。
这就是为什么"先用简单的、以后再说"在这一侧是成立的。

这条不对称在第 19 章会作为「先简后繁、方向不可逆」那条原则的九处依据之一再出现。

6. 向量成了一种列,相似度成了查询语句里的一个操作符

这一节讲第 3 级具体长什么样,因为它是最容易被低估的一个选项。

书讲的是给关系数据库装上一个向量扩展。装完之后发生的事是12:

建表的时候多一种列的类型:

CREATE TABLE job_description_table(
id integer PRIMARY KEY,
text_chunk TEXT,
embedding vector(1536) ← 就是这一列
)

↑ 括号里那个 1536 必须和你选的换算模型输出的个数对上。
对不上,存进去的时候就会报错。

查询的时候多一个操作符:

SELECT 1 - (embedding <=> '<查询的那一串数>') AS 相近程度, *
FROM job_description_table
ORDER BY 相近程度 DESC
LIMIT 20;

图说:那个 <=> 就是"算余弦距离"。
注意 "1 − 距离" 才是相近程度 —— 距离越小越像,相近程度越大越像,两者互为反面。
这个换算书只在代码里表达了,正文一次没有用文字点破。

四个操作符各对应一种算法13:<=> 余弦距离、<-> 直线距离、 <#> 内积、<+> 曼哈顿距离——正好对应第 08 章第 6 节那张表。

它真正的价值:能和条件过滤连在一起

书说得很清楚14:

PostgreSQL 做相似度搜索的威力,来自把它和条件过滤组合起来。 你可以先按标注过滤、再算相近程度:只搜当前用户有权限看的文档、 只搜某个日期之后发布的、只搜打了特定标签的。

这正是第 06 章第 4 节那道闸在这一层的实现。 书举的两个例子:法务系统只该搜用户有权查看的合同;新闻系统可能只搜最近 30 天的文章。

还有一条性能忠告15:

别在做相似度搜索的同一条查询里做复杂的多表连接,那会拖慢它。 先在子查询里过滤,再做相似度搜索。

7. 承重词一:索引 —— 20 万条要 85 毫秒

这一章第一个承重词。一句话先给结论:索引就是事先把这堆数造一份册子, 查的时候只翻册子里的一小部分,不必把每一条都算一遍。

先看现象:不建索引会怎样

书给了一组实测,这是全书唯一一组带数字的性能对照16:

数据: 20 万条职位描述,每条一串 1 536 个数
查询: "I am looking for a job as a data scientist in Berlin."

不建索引(全表扫描):
Planning Time 13.669 毫秒
Execution Time 85.582 毫秒 ← 这是把 20 万条挨个算了一遍

图说:85.6 毫秒听着不多。但第 08 章第 8 节那条选型标准是
"交互式应用要小于 100 毫秒" —— 也就是说,这已经把预算用掉了 85%,
而生成答案那一步还一步没开始。

两条明确的门槛

书给了两个数,而且方向相反,值得一起记17:

规模怎么办
不到 10 万行全表扫描常常已经够快,跳过索引
超过 100 万行索引就是必需的

中间那一段(10 万到 100 万)书没有明说,得自己测。

为什么「不到 10 万就别建」是一条真建议,不是客气话: 建索引本身要花时间和内存,而且它换来的速度是拿准确度换的(下面两节讲)。 在没必要的规模上建索引,是白付那个准确度。

怎么在两种做法之间选

书给的判据是内存18:

选哪种什么时候
多层图那种查询速度关键、而且内存够(它在内存里放的东西更多)
分片那种内存吃紧,或者你想让索引建得更快(代价是查询略慢)

书自己的结论:「对多数有几百万条向量的生产 RAG 系统,多层图那种给出最好的查询性能。」

8. 第一种做法:先把空间分片

这一节讲第一种索引怎么工作、快在哪、以及漏在哪。

它怎么建、怎么查

书讲得很清楚19:

建的时候:
把整个向量空间连同里面所有的点,分成若干片。
每一片记下一个"中心点"(它是这一片里所有点的平均位置)。
每个点同时只属于一片。

查的时候:
① 先只比"查询那一串"和各个中心点的距离 → 找出最近的那一片
② 再只在这一片里面挨个比 → 找出最近的那条

快在哪(为演示编的数):
不建索引 20 万条全比一遍
分成 30 片 先比 30 个中心点,再比这一片里的约 6 700 条
→ 一共约 6 730 次比较,而不是 200 000 次

它必然漏掉什么(书写得很坦白)

这是这一节的重心,而且书自己把它说破了20:

片 A │ 片 B

● 中心点A │ ● 中心点B

● ← 查询 │ ● ← 真正最近的那条,但它在片 B

分界线┘

发生了什么:
查询离中心点 A 更近 → 索引只去搜片 A
可真正的最近邻就在分界线那边的片 B 里 → 永远搜不到它

书的原话:"虽然那个中心点是所有中心点里最近的,
但真正的最近邻可能落在相邻的分区里、就在分界线附近。"

图说:这就是"拿准确度换速度"的具体样子 —— 它不是慢一点,是可能给你错的答案。
书接着说:"实践中这通常可以接受,因为精度损失相对小,而性能收益显著。"

上面那个「最近邻」就是「离查询那一串最近的那一条」,是这一族做法的通用叫法。

书接着补了一句判断,里面有一个词要先交代:损失——就是「和不建索引相比,少拿到了多少」。

它的原话是:这种做法在实践中通常可以接受,因为精度(取回来的到底对不对)上的损失相对小, 而性能收益显著。

这个名字要记一下:在那个向量扩展的文档里,这一族索引写作 ivfflat, 它是「倒排文件」(inverted file)的缩写21你在配置里、在建索引的语句里都会撞见它。

它的两个旋钮

lists = 30 分成几片。片越多,每片越小、查得越快,但漏掉的概率越大
probes = 3 查询时探几片。探得越多越准、越慢

书那个跑例就是 lists = 30、probes = 3 —— 也就是"分成 30 片,每次探 3 片"。

图说:这两个数是书给的。注意 probes 是一个可以事后调的补救 ——
发现漏得太多,就把它调大。

9. 承重词二:多层图索引 —— 高层是国道,底层是小街

这一章第二个承重词。一句话先给结论:多层图索引就是把这些数连成一张多层的网, 高层的路少但每条跨得远、当捷径用,越往下路越多越细,最底层才是每一条小街; 查询时从最高层一路往下跳,越跳越接近目标。

书给的那个比方

书自己打的比方很好,拿来当脚手架22:

最高层 国道图:路很少,但每条都很长

中间层 省道、县道:路多了一些,粒度细了一些

最底层 每一条小街都在

查询时:先在国道图上大跨步逼近目标城市,
再一层层下来,最后在小街上找到那个门牌号。

图说:这个比方到这里就用完了 —— 下面一律用"层""连接""候选"这些正式说法。

书的正式描述是:高层的连接少但跨度长,充当抄近路的捷径;低层的连接密,提供细粒度的导航23

三个旋钮各拧动什么

这是这一节最实用的部分24:

旋钮它管什么拧大了会怎样
m每一层里,每个点最多连几个邻居图更密 → 查询通常更快,但建索引更久、更占内存。典型值 16 到 64
ef_construction建索引时,那张动态候选表有多大索引质量通常更好(建得更慢)
ef_search搜索时考虑多少个候选结果更准、查询更慢

注意这三个的分工:前两个在建索引时起作用、一旦建完就固定了; 最后一个在每次查询时起作用,可以随时调。

所以调优的顺序是:先调 ef_search(免费、立刻见效),不够再重建索引调前两个。

别的库用什么

书顺带给了一张生态对照25:某个内存索引库支持乘积量化(把每一串数压缩着存, 省内存、略损准确度)、分片和多层图; 某个用树结构;某个只做多层图;某个三种都支持。 记住形状就够:多层图和分片这两种做法是跨库通用的,不是某一个库的私有功能。

10. 主走查:20 万条职位描述,一个查询走三遍

这是本章的主走查,前面每个机制都在它上面占一步。 用的是书那个真实跑例16

(20 万条、85.582 毫秒、13.927 毫秒、lists=30、probes=3、m=16、ef_search=50 都是书里的真实数;下面的比较次数、片内条数是我们为演示算的。)

第 1 步:建表

CREATE TABLE job_description_table(
id integer PRIMARY KEY,
text_chunk TEXT,
embedding vector(1536)
)

灌进 20 万条职位描述:每条一段文字 + 它那 1 536 个数。

第 2 步:提问

查询:"I am looking for a job as a data scientist in Berlin."
↓ 用同一个换算模型
[0.0187, -0.0342, …共 1 536 个]

第 3 步:不建索引,全算一遍

SELECT 1 - (embedding <=> '<那一串数>') AS 相近程度, *
FROM job_description_table
ORDER BY 相近程度 DESC
LIMIT 20;

实测: Planning 13.669 毫秒 · Execution 85.582 毫秒
发生了什么:20 万次余弦相似度计算,一次不落。

第 4 步:建第一种索引(分片),再查一遍

CREATE INDEX ON test_embedding_table
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 30);
SET ivfflat.probes = 3;

比较次数(我们算的):
30 个中心点 + 3 片 × 每片约 6 667 条 ≈ 20 030 次
而不是 200 000 次

实测结果:书只给了一句话 —— "大约比全搜索快一倍"。

图说:书这里没给具体毫秒数,只给了倍数。
按 85.582 折半,大约是 43 毫秒上下,但这是我们推的,不是书里的数。

第 5 步:建第二种索引(多层图),再查一遍

CREATE INDEX ON test_embedding_table
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 200);
SET hnsw.ef_search = 50;

实测: Planning 1.109 毫秒 · Execution 13.927 毫秒

对照:
全表扫描 85.582 毫秒
多层图 13.927 毫秒 ← 快了约六倍

第 6 步:把这三次放在一起看

执行耗时 比较次数(量级) 可能漏掉最近邻?
全表扫描 85.582 ms 20 万 不会
分片索引(30/3) 约 43 ms 2 万 会(分界线那边)
多层图(16/50) 13.927 ms 几千 会(高层跳过头了)

图说:三行的排序是一致的 —— 越快,越有可能漏。
而书的态度是:这个损失"实践中通常可以接受"。

注意最后一列。 第 08 章讲的余弦相似度是精确的; 而这一章讲的索引是近似的——它返回的是「很可能是最近的那几条」,不是「一定是」。

判断(我们的,不是书里的):这个从「精确」到「近似」的切换, 是这套系统里少数几个「悄悄发生、而且没人告诉你」的变化之一。 你建了一个索引,查询语句一个字没改,返回的结果集从「保证正确」变成了「大概率正确」—— 而且没有任何报错、没有任何日志、没有任何提示。 书把机制讲清楚了,但没有把这个「性质变了」说破。 如果错,会错在: 如果你的场景本来就允许近似(绝大多数按意思搜的场景都允许), 那这个变化确实无关紧要,不值得特意提醒。 判据是:你的系统里有没有哪个功能默认「取回来的第一条一定是最像的那条」。

11. 作者的判断与证据

说法它是什么
相似度搜索 vs 语义搜索的区分是术语澄清,书写得很准
四步决策路径作者的做法归纳。 每一步的问题都合理,但没有任何一步有数据支撑
「多数团队照基准选而不是照工作流选」作者的观察,没有来源
四类生态的划分是事实描述,和市场现状一致
三级阶梯每级多给什么是事实描述,由各自的功能决定
「换库要重建索引但不必重算那些数」是事实,而且是这一章最硬的一条
那两个数据库的反面判据(几十万条、10 毫秒、几亿条)作者给的经验阈值,没有来源
85.582 / 13.927 毫秒是书里的真实实测,而且是全书仅有的两组实测之一。但测试机器的配置书没有交代
「分片索引大约快一倍」书只给了这句话,没给毫秒数
「不到 10 万不必建、超过 100 万必须建」作者给的经验数,没有来源
分片索引会漏掉分界线那边的最近邻是机制推导,而且书自己坦白了
「精度损失相对小,性能收益显著」作者的判断,没有测量。 「相对小」是多小,书没说
三个旋钮各管什么是那个扩展的实现事实;m 的典型值 16–64 是常见配置

12. 边界与局限

  • 没有交代实测的机器配置。 85.582 毫秒是在什么样的机器上、多少内存、 索引有没有全部装进内存?这些书一个字没提,所以这个数只能当量级看,不能当基准;
  • 没有量过「漏掉多少」。 分片索引会漏,书承认了,但漏的比例是多少一个字没有—— 而这恰恰是「值不值得换」的关键数;
  • 没有讲索引要建多久。 20 万条建一次多层图索引要几分钟? 书只说「建索引更久」,没有数;
  • 没有讲增量。 新加了 1 万条,索引要重建吗?全书没讲;
  • 没有讲怎么验证索引真的被用上了。 书只在一个提醒里说「可能需要强制关掉顺序扫描」26, 但没说怎么判断当前这次查询到底走没走索引。

13. 可带走的

  1. 先把两个说法分开:「相似度搜索」是技术操作(找空间里最近的几串), 「语义搜索」是面向用户的能力(按意思搜)。后者用前者实现;
  2. 选库不是选型题,是一条四步路径: 是不是线上应用 → 要不要和业务数据待在一起 → 会不会长到几千万条 → 再拿四个现实问题筛一遍;
  3. 照工作流选,不照榜单选。 几千个块的原型不需要分布式的向量数据库;
  4. 它们其实是四类东西: 内存索引库 / 进程内嵌存储 / 带向量扩展的数据库 / 专门的向量引擎。 最常见的三个排成一条阶梯,每一级只比上一级多一点;
  5. 换库不贵:要重建索引,但不必重算那些数——而那才是贵的部分。 (对照第 02 章:换换算模型才是真贵,因为贵的那部分躲不掉);
  6. 装了向量扩展之后,向量成了一种列、相近程度成了查询语句里的一个操作符。 建列时的维数必须和换算模型对上;1 − 距离 = 相近程度;
  7. 它真正的价值是能和条件过滤连在一起(只搜有权限的、只搜近 30 天的)—— 这就是第 06 章那道闸的实现。但别在同一条查询里做复杂的多表连接;
  8. 索引 = 事先造一份册子,查的时候只翻其中一小部分。 实测:20 万条全算一遍 85.6 毫秒,多层图索引 13.9 毫秒,快约六倍;
  9. 两条门槛:不到 10 万行常常不必建;超过 100 万行必须建;
  10. 第一种做法是分片 + 中心点: 先比中心点找到最近的那一片,再只在片内找。 它必然漏掉「真正最近但落在分界线那边」的那一条。名字写作 ivfflat;
  11. 第二种做法是多层图: 高层路少但跨度长当捷径,低层密而细。 三个旋钮:每点最多连几个邻居、建索引时的候选表多大、搜索时看几个候选。 前两个建完就固定,最后一个随时能调——所以先调它;
  12. 建了索引之后,结果从「保证是最近的」变成了「大概率是最近的」, 而这个变化不会报错、不会有日志。

14. 原文地图

主题原书章原文位置
时间线与「不一定非要加一个专门的库」Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:6(搜「FAISS was released in 2017」)
相似度搜索 vs 语义搜索Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:14(搜「Semantic search is implemented」)
四步决策路径Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:26(搜「Use the following decision path」) · text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:42(搜「live next to your business data」)
四个现实问题Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:71(搜「Practical questions for vector database selection」)
为什么需要专门的向量库Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:177(搜「not optimized for nearest neighbor search」)
照工作流选不照基准选Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:181(搜「choosing based on benchmarks instead of workflow」)
生态四类Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:32(搜「vector library」)
换库不必重算Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:198(搜「which is the costly part」)
三级阶梯Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:295(搜「adds lightweight persistence」)
第 1 级的适用面Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:289(搜「doesn’t require persistence between runs」)
第 2 级的反面判据Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:409(搜「beyond a few hundred thousand vectors」)
维数必须对上Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:499(搜「1,536 dimensions because this recipe uses」)
向量成列、相似度成操作符Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:570(搜「native vector columns alongside your application data」)
第 3 级的反面判据Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:574(搜「hundreds of millions or billions of vectors」)
四个操作符Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:631(搜「the <=> operator」)
和条件过滤组合Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:676(搜「combining it with SQL filtering」)
别做复杂多表连接Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:680(搜「Filter first in a subquery」)
全表扫描实测Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:743(搜「data scientist in Berlin」) · text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:760(搜「Execution Time: 85.582 ms」)
分片索引的建法与「快一倍」Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:779(搜「lists = 30」) · text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:792(搜「roughly twice as fast」)
多层图实测Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:828(搜「Execution Time: 13.927 ms」)
两条规模门槛Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:832(搜「Above one million rows, indexing becomes essential」)
两种索引怎么选Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:834(搜「Choose HNSW when query speed is critical」)
分片索引的机制与它的漏Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:840(搜「IVF stands for inverted file」) · text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:844(搜「could be in an adjacent partition」)
多层图的机制与那个比方Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:851(搜「builds a multilayer graph」) · text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:853(搜「national highway map」)
三个旋钮Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:838(搜「maximum number of connections per layer」)
别的库用什么索引Chapter 6. Vector Databases and Similarity Searchestext/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:857(搜「product quantization」)

Footnotes

  1. 出处:「Chapter 6. Vector Databases and Similarity Searches」第 14 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:14,搜「Semantic search is implemented」)。这一章开头还给了一条时间线,可以当时代坐标:2017 年出现第一个广泛使用的向量索引库,2019 到 2023 年之间陆续出现了几家专门的向量数据库,与此同时传统数据库也在自己的平台上加了向量搜索功能——见同章第 6 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:6,搜「FAISS was released in 2017」)。

  2. 出处:同章第 26 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:26,搜「Use the following decision path」)起的四步;第 2 步那句「要不要和业务数据待在一起」见第 42 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:42,搜「live next to your business data」)。

  3. 出处:同章第 71 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:71,搜「Practical questions for vector database selection」)是表 6-1 的表题,四问分列其后。

  4. 出处:同章第 181 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:181,搜「choosing based on benchmarks instead of workflow」)。

  5. 出处:同章第 32 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:32,搜「vector library」)起。为什么需要专门的向量库,见第 177 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:177,搜「not optimized for nearest neighbor search」):传统数据库没有为高维向量的最近邻搜索做优化,而现代嵌入模型产出几百到几千维的向量,暴力搜索太慢。

  6. 出处:同章第 6 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:6,搜「Elasticsearch」)。

  7. 出处:同章第 295 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:295,搜「adds lightweight persistence」)。补充(不在书里,来自通用知识):「事务」指一组数据库操作被当成一个整体——要么全部生效,要么全部回退,不会停在中间状态。

  8. 出处:同章第 289 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:289,搜「doesn’t require persistence between runs」)。书举的典型场景是「一次性分析任务」:建索引、查、然后丢掉——比如分析一份合同抽取当事方和日期,向量搜索只在那个处理作业期间需要。

  9. 出处:同章第 409 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:409,搜「beyond a few hundred thousand vectors」)。同一节还有一条工程建议值得记:原型阶段可以用它内置的自动生成嵌入的功能,但如果你打算以后迁走,就在自己的代码里生成那些数、只拿它存和搜——见第 329 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:329,搜「generate embeddings in your own code」)。

  10. 出处:同章第 574 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:574,搜「hundreds of millions or billions of vectors」)。

  11. 出处:同章第 198 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:198,搜「which is the costly part」)。

  12. 出处:同章第 570 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:570,搜「native vector columns alongside your application data」);维数必须对上见第 499 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:499,搜「1,536 dimensions because this recipe uses」)。「1 − 距离 = 相近程度」这个换算,书只在代码里表达,正文没有用文字点破——见第 782 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:782,搜「1 - (embedding <=>」)。

  13. 出处:同章第 631 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:631,搜「the <=> operator」)。四个操作符的完整清单在其后几段。

  14. 出处:同章第 676 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:676,搜「combining it with SQL filtering」)。

  15. 出处:同章第 680 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:680,搜「Filter first in a subquery」)。

  16. 出处:查询语句与数据集见同章第 743 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:743,搜「data scientist in Berlin」);全表扫描的实测见第 760 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:760,搜「Execution Time: 85.582 ms」);20 万条这个规模见第 792 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:792,搜「200,000 job descriptions」);多层图的实测见第 828 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:828,搜「Execution Time: 13.927 ms」)。书没有交代测试机器的配置。 2

  17. 出处:同章第 832 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:832,搜「Above one million rows, indexing becomes essential」)。

  18. 出处:同章第 834 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:834,搜「Choose HNSW when query speed is critical」)。

  19. 出处:同章第 840 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:840,搜「IVF stands for inverted file」)。

  20. 出处:同章第 844 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:844,搜「could be in an adjacent partition」)。「实践中通常可以接受」那句见第 849 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:849,搜「acceptable」)。

  21. 出处:建索引的语句见同章第 778 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:778,搜「USING ivfflat」),两个旋钮见第 779 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:779,搜「lists = 30」)与第 781 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:781,搜「ivfflat.probes = 3」)。「inverted file」这个全称见第 840 段。

  22. 出处:同章第 853 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:853,搜「national highway map」)。

  23. 出处:同章第 851 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:851,搜「builds a multilayer graph」)。这一族索引的名字缩写是 HNSW。

  24. 出处:同章第 838 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:838,搜「maximum number of connections per layer」)。跑例用的参数见第 798 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:798,搜「m sets the maximum number of connections」)一带的建索引语句。

  25. 出处:同章第 857 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:857,搜「product quantization」)。

  26. 出处:同章第 766 段(text/08-ch06-chapter-6-vector-databases-and-similarity-search.txt:766,搜「disable sequential scans」)。原文说数据库有时会在不确定索引更划算时退回顺序扫描。