以我的项目为例
使用到的数据库有postgres、milvus以及图数据库neo4j,除了数据库外还用了es作为搜索引擎
其中只有postgres、milvus存储了语义转化后的向量值
为什么这么分:
PG存向量JSON:持久化+事务+去重UNIQUE(doc_hash,chunk_idx),但JSONB只能暴力算余弦,量大不行,只做兜底TF检索。这里的关键是doc_hash能保证同一文档不会重复入库,chunk_idx则记录分块顺序,方便后续按原文位置回溯。虽然JSONB存向量后无法走索引加速,只能逐行计算余弦相似度,数据量一上来性能就崩,但作为兜底方案,处理低频关键词召回已经足够。Milvus存向量:专做高维ANN,2048维IVF毫秒级TopK,PG做不到。Milvus 的核心优势在于IVF索引把向量空间划分成多个子簇,查询时只扫描最相关的几个簇,配合2048维的高维向量,依然能保持毫秒级响应。相比之下,PG 的暴力扫描在百万级向量下会退化到秒级甚至更慢,完全无法支撑实时检索场景。ES只存文本:专做BM25倒排,补语义漏掉的精确词/型号/人名。ES也能存dense_vector做kNN,但本项目不需要:一是运维/调参双写成本,二是ES kNN大规模不如Milvus,三是混合检索要两路独立排序再RRF,放一起就失去正交性了。具体来说,BM25擅长处理精确匹配,比如用户搜"RTX 4090"这种型号词,语义检索可能把它当成普通名词,而BM25能精准命中;RRF融合时,两路检索各自独立打分再合并排名,才能发挥互补优势,如果都塞进 ES 就退化成单路检索了。
一句话:PG=账本,Milvus=语义检索引擎,ES=关键词检索引擎。
补充:
JSONB:即postgre里面存的json的二进制形式
为什么Milvus能毫秒级,PG做不到:milvus里有特殊的索引结构
ann&knn:
KNN:精确最近邻,全量算完取最小的K个,保证100%准,但慢。ANN:近似最近邻,用IVF/HNSW等索引,用损失一点精度换10~100倍速度。比如召回率95%但只要5ms。RAG召回本来就要TopK再让LLM重排,丢5%完全可接受。