我们做 AI 数据库选型,走了三个月弯路才发现问错了问题
去年底我们启动了一个企业知识库项目,四万份文档,做完切块大概八十万条向量。
按当时的判断,这是个"小项目",难点在检索效果。于是我们的第一件事是——选数据库。
选型会开了七轮,参评五家,功能对比表拉了两页。第七轮结束的时候,我们手里握着一份所有人都说"都很强"的清单,候选名单还是那五家,一个都没砍掉。
后来项目差点没上线。今天回头看,那次选型从一开始就问错了问题。
一、第一个错误:问"支持什么",不问"我要多少"
我在会上问的第一个问题是"你们支持多少维向量"。
五家都说支持 1536 维、支持余弦距离、支持 HNSW。这个问题没有任何区分度,因为它是 2026 年的入场券,不是差异点。
真正该问的是另一句:我们要存多少条向量。
这个数字我们一直没算过。八十万条——是我们上线前一周才算清楚的。算法很简单:
文档数 × 平均切块数 × 每条块的平均向量数
4 万份 × 20 块 = 80 万条
八十万条,768 维,float32,一条 3KB。总共不到 3GB 原始数据,加上 HNSW 图结构,一台 16GB 的普通实例就装下了。
在这个规模上,任何产品都不会成为瓶颈。 所以我们花三个月开的那七轮会,选的是"哪个产品更不会拖后腿",而实际上没有一个会拖后腿。
最后我们装的是现成的 PostgreSQL 加 pgvector,一周跑通端到端。
这不是说 pgvector 最好。是这个规模上,任何一个方案都够用,选型的边际价值接近于零。
选型的价值不来自"比得有多细",来自"要不要选"。百万条以内,答案是不要选,用你已有的库。
二、第二个错误:把 demo 当成了 POC
第二件事更让我们难受。
选型过程中,我们看了五家的 demo。所有产品在十万条数据上都跑得飞快,响应都在毫秒级。我们据此判断"性能都没问题"。
这个判断是错的,原因有三层。
第一层,demo 的数据量比我们小八倍。 十万条和八十万条,在 HNSW 上是两种不同的检索路径。小数据量下 kNN 图够用,数据量上来之后才能看出图的构建质量和召回稳定性。
第二层,demo 用的是标准数据集,我们用的是自己的数据。 标准数据集的向量分布均匀,我们的文档向量非常不均匀——有大量几乎重复的制度文件,也有大量独特的合同条款。分布不均匀的时候,HNSW 的召回率比 demo 里差得多。
第三层,demo 没人看执行计划。 我们后来自己测的时候发现,有几家的产品在过滤条件下没走索引,退化成全表扫描。这个问题在 demo 里完全看不出来,因为 demo 不带过滤条件。
把 demo 当 POC 的代价是:我们上线后第一周,业务方反馈"搜不准",而当时我们没有能力判断这是检索的问题、切块的问题、还是模型的问题——因为我们没做评测集。
三、第三个错误:没有评测集就开始调参
这是三个错误里最伤的一个。
上线后业务方说"不太准",这句话在我们手里无法定位。我们改了切块大小、换了 embedding 模型、调了索引参数,每一次改动之后都觉得"好像好一点",但没有任何一次能证明。
因为没有基线。
后来我们补了一件事,花了两个下午:
1. 从真实业务问题里挑 50 条,覆盖高频和长尾
2. 每条人工标出「正确的 10 个结果」
3. 系统返回 Top10,算命中数 / 10,五十条取平均
4. 换切块参数、换模型、换索引,都重跑这五十条
这个指标叫 recall@10。做完之后,之前"好像好了一点"的那些改动,有一半实测是下降的——我们凭感觉调的那半个月,有一半时间在往反方向走。
关键在第二步。 标注集必须来自你自己真实的业务问题。我们一开始试着用 LLM 生成一批问题,测出来分数很高,修出来的系统上线后还是被吐槽。生成的问题和真实问题不是同一个分布。
四、三个错误背后,是同一个判断失误
回头看,三个错误的根子是同一个:我们一直在问产品能做什么,没问我们要花多少钱。
这里的钱不只是软件授权。有三笔账当时我们都没算:
第一笔,内存账。 我们只算了原始向量的 3GB,没算 HNSW 图结构和副本。如果当时是千万级项目,这笔账会差出三倍——按 30GB 报预算,实际要 80 到 100GB。这一笔在采购会上是会被追责的。
第二笔,人的账。 一套新引擎意味着新的备份体系、新的监控、新的值班手册、新的人。这些不进采购单,但会如实进年度预算。百万级以内,这笔人力账往往比软件授权贵。
第三笔,治理的账。 我们是内部知识库,暂时不涉及敏感数据。但同期的另一个项目在金融场景,他们把向量放进了独立向量库,结果审计来问"这个 Agent 读了哪些行"的时候,要翻三份日志才能拼出来。这不是技术问题,是治理问题,事后补不回来。
第三笔账最贵,因为它不在上线前暴露,在上线后被审计暴露。
五、如果重来一次,我会怎么问
如果这个项目重新做,我的选型会是这样,四步,两周走完:
第一步,算出向量条数。 不估算,算准确值。这个数决定后面所有事情。
第二步,算出内存和延迟预算。 原始向量 + 索引结构 + 副本 + 增长余量,折算成三年成本。这一步做完,候选名单通常自动剩两三家。
第三步,用真实数据做 POC,四项指标。 不看 demo,直接灌自己的数据。
| 指标 | 怎么测 |
|---|---|
| recall@10 | 50 条真实问题,人工标正确结果,算 Top10 命中率 |
| 真实并发 P99 延迟 | 用你的查询压,不看平均值 |
| 每百万向量内存占用 | 折算成钱,算三年 |
| 换 embedding 是否全量重建 | 直接问,要他们给时长 |
第四步,问退出成本。 向量与索引元数据能不能以标准格式导出。一开始谈退出确实不吉利,但锁住你的不是数据,是语义资产——embedding 模型、切块策略、索引参数。这三样导不出来,换库等于重新开始。
这四步里,第一步最关键,也最容易被跳过。因为它不涉及任何产品,只涉及你自己的数据,看起来不像"选型工作"。但正是这一步决定了选型要不要做。
六、关于混合场景的一点补充
我们这个是纯文本知识库,相对简单。后来在另一个项目里接触到结构化数据和向量并存的情况——金融、政务、制造都有,业务表、权限、审计、向量检索要在一起。
这一档的难点不是性能,是治理。技术上的判断方法很简单:把数据库和外网断开,它还能不能把一段文本变成向量、并检索出结果。 能,就是库内完成;不能,就还有库外环节。
还有个更直接的判定器,写一条 SQL 就知道:
-- 语义召回 + 关系过滤 + 时间过滤 + 排序,一条 SQL 完成
SELECT c.contract_id,
1 - (e.embedding <=> :query_vec) AS similarity
FROM contract_chunk e
JOIN contract c ON c.contract_id = e.contract_id
WHERE (e.embedding <=> :query_vec) < 0.35
AND c.sign_date >= DATE '2024-01-01'
ORDER BY e.embedding <=> :query_vec
LIMIT 20;
这条跑不通,说明向量召回和结构化过滤得拆成两次查询在应用层拼,胶水代码会变成长期负担。
这条路上国内有代表性的做法是电科金仓的 KES AI 数据库,核心主张是"数据不出库"——embedding 生成、检索、权限、审计都在库内,所以"Agent 读了哪些行"能用一条 SQL 回答。另外阿里云的 AI 原生数据库是从云上新构产品线,Oracle 26ai 是往存量旗舰库长能力,入口不同,选哪个取决于你最缺什么。
最后
我们那个项目最后上线了,效果还行。但那三个月选型会开完之后,我对"选型"这件事的看法变了。
选型不是把候选产品比细,是先判断要不要选。
百万级根本不用比,千万级先算内存账,亿级先怀疑自己的容量规划。真正需要仔细比较的只有一格——结构化数据和向量同时存在、且不能出库的那一格。
其他格子里,比的功夫花在功能表上,收获的都是零。
本文基于公开信息与真实项目经验独立撰写,不代表任何厂商立场。厂商公布的性能数据均标注为官方口径,未经独立复测。
李白客,信创行业独立观察者。关注数据库、AI 基础设施与国产化替代。

浙公网安备 33010602011771号