考察点
「向量数据库对比做过吗?Qdrant 性能如何?量级多大?有没有瓶颈?」是面经里的原题。面试官在探你的工程深度:是否真扛过量级,是否理解 ANN 索引的召回率-性能权衡,以及有没有「向量库不是必选项」的判断力。追问常走 HNSW 参数、标量过滤、分库分表。
参考答案
先明确:向量检索的两个核心权衡
所有向量库的内核都是 ANN(近似最近邻)索引,主流是 HNSW 图索引。它用一点点召回率换数量级的速度:暴力精确检索百万级向量要几百毫秒,HNSW 压到几毫秒,代价是 Recall 从 100% 降到 95%-99%(可调)。选库本质是在四个变量上权衡:数据量级、QPS、标量过滤需求、团队运维能力。
主流方案对比
| 方案 | 优势 | 短板 | 适合量级 |
|---|---|---|---|
| pgvector | 复用 PostgreSQL,事务/权限/JOIN 全有,零新组件 | 10万-百万级后性能衰减明显,过滤+向量混合查询一般 | 百万以下,团队已有 PG |
| Milvus | 功能最全,分布式,GPU 加速,索引类型多(IVF/HNSW/DiskANN) | 部署重,运维成本高 | 千万级以上 |
| Qdrant | Rust 实现性能好,标量过滤强,部署轻(单二进制) | 集群能力弱于 Milvus | 百万到千万 |
| Elasticsearch/OpenSearch | 向量+BM25 一体,天然混合检索 | 纯向量性能一般,内存吃紧 | 已有 ES 栈的团队 |
| Redis/FAISS | 内存级延迟 | Redis 成本高;FAISS 只是库不是服务,得自己包 CRUD | 缓存层/嵌入式 |
我项目里的选择逻辑
中小规模(百万 chunk 内)用 Qdrant 或 pgvector:Qdrant 胜在标量过滤——企业知识库的权限隔离就是 filter: dept_id in [...] 这种过滤和向量搜索的组合,Qdrant 对此有专门优化,过滤后仍然走 HNSW 图而不是退化成暴力扫。pgvector 胜在不用引入新中间件,元数据直接和 chunk 表 JOIN。
真正到千万级以上、QPS 上千才需要 Milvus 集群。大多数 RAG 项目死在这一步之前——瓶颈从来不是向量库,是切分和 Embedding 质量。
HNSW 参数经验
m(每个节点的边数,Qdrant 默认 16):越大图越稠密,召回率高但内存和建索引时间涨。16-32 是常见区间。ef_construct(建索引时的搜索宽度,默认 100-200):影响索引质量,离线成本,可以开高一点。ef_search(查询时宽度,运行时参数):在线调召回率-延迟的旋钮,延迟敏感时调低,Bad Case 多的时候调高验证是不是检索丢了。
常见瓶颈与解法
- 过滤后召回率骤降:过滤条件太苛刻(比如命中 1%),HNSW 图上可走节点太少。解法是提高
ef_search或换支持预过滤的索引。 - 内存:HNSW 全驻内存,千万级 1024 维向量光向量就要几十 GB。开量化(PQ/SQ8,精度换内存,通常损失 1-2 个召回点)或上 DiskANN。
- 写入与实时性:频繁增量更新导致段合并开销。把实时性要求高的文档单独建 collection,主库 T+1 重建。
可能的追问
Q:为什么不直接用 FAISS? FAISS 是索引库不是数据库——没有增删改服务、没有过滤、没有持久化语义、没有权限。demo 用它,生产要自己包一层服务,等于重新发明 Qdrant。
Q:向量库怎么做高可用? 中小规模用 Qdrant 自带的副本集;再上一层的保障是索引可重建——原始 chunk 和元数据永远存一份在 MySQL/PG 里,向量库挂了能从源数据重建,这是底线设计。
Q:多租户怎么隔离? 三种粒度:独立 collection(隔离最彻底,租户少时用)、单 collection 加租户字段过滤(租户多时用)、payload 索引加速过滤。权限过滤必须在检索层做,不能依赖生成侧「别说不该说的」。