研究了500篇论文和几个顶级向量数据库后,我决定公开这条震惊结论!
最近用AI读了500多篇论文, 其中向量搜索、图、AI相关的论文可能有不下100篇.
同时用AI仔细阅读了市面上几个顶级的开源向量数据库源码/传统数据库向量功能/图数据库.
我得出一条震惊结论:
凭什么单机下面普通的标量查询动不动就几十万上百万的QPS, 向量数据库最多干到几千上万就歇菜了? 只能说明向量数据库还有很多技术突破点, 并且大有前途! 谁先突破谁就能赢得未来. 国产数据库完全可以带个头, 先干到到单机10万qps!绝不能让开源代表最高水平啊!
别着急反驳, 说什么OLAP不也一样? 若干年前能干到几千的实时数仓已经是顶级产品了. 别瞎说, 如果止步不前, 今天就没有DuckDB霸榜ClickBench, 某些云数据库也享受不到DuckDB计算引擎加持的极致分析能力了! 更何况向量检索又不需要像OLAP那样访问很多很多的数据然后进行大量计算得出少量结果, 向量搜索只需要访问少量数据库返回少量记录!
向量维度高, 一个值很大, 返回几十条这么大的值QPS上万已经很不容易了, 是, 是不容易! 这不正好可以突破么, 不容易说明数据压缩、数据结构设计可以优化啊! 单机干到10万qps也只是普通标量查询的十分之一甚至更低, 我认为是非常理性的目标了!
列举一些重要的参考文档如下( 原文在 https://github.com/digoal/blog ):
- 《2025-Milvus 源码入门学习31篇 汇总》
- 《2025-VectorChord 源码入门学习39篇 汇总》
- https://github.com/VectorDB-NTU/RaBitQ-Library
- 《2025-pgvector 源码入门学习27篇 汇总》
- 《pgvectorscale 源码学习: 3.1 索引构建 (Index Building)》
- 《2025-OceanBase 源码入门学习24篇 汇总》
- 《2025-DuckDB 源码入门学习27篇 汇总》
- https://github.com/duckdb/duckdb-vss
- https://github.com/dais-polymtl/flock
- 《AI搜索“不等于”向量搜索, 那么答案究竟是什么?》
- 《谁说国产只会套壳, 这个国产向量数据库就不是pgvector套壳》
- 《容器体验VexDB! 暴露PostgreSQL,openGauss,vastbase基因》
- 《VexDB BM25 算法的全文检索 fulltext 索引原理与实践》
- 《VexDB HybridAnn 向量标量混合索引原理与实践》
- 《VexDB DiskANN 图索引原理与实践》
- 《VexDB Graph_Index 图索引原理与实践》
- 《AI与数据库的共生融合:能力、创新与未来范式》
- 《深度研究报告 | AI 智能体所需的数据库产品及未来发展趋势》
- 《AI论文解读 | 深入解读《从第一性原理设计智能生态系统》:主动推断与未来AI , Designing Ecosystems of Intelligence from First Principles》
- 《AI论文解读 | KAG: Boosting LLMs in Professional Domains via Knowledge Augmented Generation》
- 《AI论文解读 | From Local to Global: A GraphRAG Approach to Query-Focused Summarization》
- 《AI论文解读 | Retrieval-Augmented Generation with Graphs (GraphRAG)》
- 《AI论文解读 | RAG vs. GraphRAG: A Systematic Evaluation and Key Insights》
- 《DeepSeek 最新 "OCR-上下文光学压缩" 论文的重大意义 : 向量数据库的筒子们又有活干了》
- 《混合搜索的三大技术流派, 差异在哪? 哪个更有前途?》
- 《PostgreSQL 在资源搜索中的设计 - pase, smlar, pg_trgm - 标签+权重相似排序 - 标签的命中率排序》
- 《PostgreSQL结合余弦、线性相关算法 在文本、图片、数组相似 等领域的应用 - 2 smlar插件详解》
- 《PostgreSQL结合余弦、线性相关算法 在文本、图片、数组相似 等领域的应用 - 1 文本(关键词)分析理论基础 - TF(Term Frequency 词频)/IDF(Inverse Document Frequency 逆向文本频率)》
- 《向量插件新贵 VectorChord(IVF+ RaBitQ量化), pgvector 和 milvus 都被秒杀了》
- 《AI论文解读 | 向量ANNs方法之 RaBitQ: Quantizing High-Dimensional Vectors with a Theoretical Error Bound for Approximate Nearest Neighbor Search》
- https://arxiv.org/pdf/2205.13147
- 例如, Redshift 并非为完全任意字段的高效索引而设计(不像传统行式数据库的 B-tree 索引),但通过 Sort Key + Zone Maps + 列存 + 自动优化 的组合,可在实际应用中实现高效的聚集存储与多维查询优化。
- 《解密ADB PostgreSQL数据库metascan特性(存储级、块级、batch级过滤与数据编排)》
- 《DuckDB 存储编排优化 之 任意字段组合过滤》
- 《从一维编排到多维编排,从平面存储到3D存储 - 数据存储优化之路》
- https://www.cs.cmu.edu/~15721-f24/papers/Redshift_Revinvented.pdf
- file:///Users/digoal/Downloads/AmazonRedshiftPerformanceTuningandOptimization.pdf
下面我结合自己的理解, 我想分享一下“面向AI 搜索的数据库索引设计和优化思考”.
一、任何设计都应该围绕需求
AI应用如此之火, 主要在于AI Agent的应用爆发, 例如:
- 客服助手: 例如某个商品遇到什么报错, 如何解决?
- 代码助手: 例如写好伪代码, 让代码助手编写相关代码
- 理财助手: 例如根据股票数据、新闻等综合预测股票价格走势
- 学习助手: 解释知识点、讲解疑难问题等
每种AI助手都需要数据库来存储助手与每位用户的 会话记录 , 这样助手才不至于像健忘症(阿兹海默症)患者一样, 每次和它对话都需要把之前说过的背景再说一遍. 核心是在每一轮对话中获得与当前对话相关的上下文, 然后再进行推理.
每种AI助手还需要外部知识库来支撑更精准的推理, 因为模型是静态的, 用来训练模型的素材是过去已知且公开的数据, 训练之后产生的新知识、新数据, 或未公开的数据, 模型的回答肯定是不准确的.
外部知识库通常可能包括:
- 未公开资料, 比如产品说明书
- 代码库
- 实时产生的内容(聊天记录、新闻、产品迭代手册或代码、实时归档的知识库等)
总结一下AI助手对数据库的核心需求(也就是典型的RAG场景, KV Cache数据库推理加速不在此文讨论!):
有了以上素材, 数据应该如何组织? 才能实现在每一轮次的对话中, 帮助大模型快速找到所有与之相关、并且按相关程度排序好的素材?
本文主要聚焦在RAG场景对数据库的需求, 细节处则将重点放在向量搜索上.
PS: AI 搜索的需求最主要的来自RAG场景, 但要理解AI 应用绝非只有RAG.
以上转化为数据库的需求:
- 输入查询请求, 快速得到所有与查询请求相关的结果
- 每条结果应该有一个相关性得分
首先需要对知识进行切分, 切分方法举例:
- 句子
- token 数
- 段落
- overlap
- 特殊格式(例如markdown)等
对查询请求进行分类, 为了得到最佳效果, 不同分类在数据库中的存储、索引组织方式完全不一样:
- 语义相关性, 属于向量搜索范畴. 需先对原始内容进行embedding处理(使用embedding模型即可转换).
- 稀疏向量, 通常用于有限字典的token, 往往每个值代表一个token. 因为token本书有意义, 通常无法通过量化来降低精度. 计算相交、包含某些特定token. (有点类似smlar插件原理)
- 稠密向量, 通过计算向量空间距离(欧式距离、cosine(夹角)、内积...)来得到相关性
- 二值向量, 通常用于匹配位数差异, 例如 海明距离. 或者位数差异占比.
- 关键词匹配, 属于全文检索范畴.
- 精确匹配, 属于传统关系数据库搜索范畴(标量类型 等于、不等于、大于、小于、范围等, 多值类型: 包含、不包含、相交等). 例如精确匹配某个商品名、代码的某个类/函数、股票代码等.
- 以上查询的组合需求, 属于混合搜索范畴
为了满足相关性排序要求, 需要对每一条结果计算相关性得分, 根据相关性得分进行排序, 计算方法举例如下:
- 全文检索, bm25算法. (考虑到关键词在所有chunk中出现的频率(越高则得分越低)、在当前chunk中出现的频率(越高则得分越高), 计算综合得分. 公式这里不给出, 请参考之前的文档)
- 向量搜索, reranking. 通常可使用reranking LLM来进行计算得分.
- 混合搜索, RRF算法. 根据每种搜索的
权重*得分进行综合计算和排序.
为了覆盖到所有相关的上下文, 往往还需要对查询结果再度进行扩展, 扩展方法:
- 结果的相关上下文, 属于图式搜索范畴, 例如在对知识进行切分后, 保留chunk的章节、关键词等信息, 通过图数据库搜索方法进行关联.
- 边界扩展, 获取切分后的chunk的前面以及后面的若干个相邻chunk, 防止缺少上下文.
最后, 去除重复chunk, 按相关性顺序返回给用户搜索结果.
二、任何优化都应该充分考虑环境因素
数据库所处的硬件环境, 例如:
- 存储: IO带宽, IOPS, IO RT
- 内存
- CPU: 核数、主频、SIMD支持情况等
- GPU (下面没有讨论GPU加速, 实际上是可以想想的, 特别在量化后的bit运算加速上是有潜力的比鸭数据库(DuckDB)快10倍, 狼数据库(Sirius)诞生!)
如何在有限条件下, 解决最大的瓶颈问题.
当然, 如果要突破单机资源限制, 也可以有分布式, 例如 milvus, 类似分库分表在向量数据上的设计. 纯随机分布, 或根据向量空间划分不同的分区, 将数据路由到对应分区中.
三、没有衡量标准的设计注定会“失败”
天下武功唯快不破?
大错特错!
为什么? 举个例子, 向量索引采用了牺牲精度的近似搜索方法(可能找到的结果相关性和实际的相关性不一样), 至少得加个定语: 精度可接受的情况下, 唯快不破.
在设计数据库索引时, 应该考虑如下衡量指标:
- 数据体量: 最多多少条数据, 依旧能满足以下指标.
- 查询精度: 要求召回率多少(TOP-N条结果中包含真实相关结果的占比)
- 查询延迟: (返回TOP-N条数据, RT多少?)
- 查询并发: 以上查询的并发QPS能达到多少
- 写入延迟: 在创建了各种所需索引(例如标量索引、全文索引、向量索引)的情况下, 插入1条数据(包含所需字段: 例如 原始字段、向量字段、tsvector字段等)的RT多少?
- 写入并发: 针对以上写入请求, 每秒最多能写入多少条.
- 创建索引的速度: 在写入N条记录后, 创建索引的耗时
- 并发重建索引的速度: 不影响DML的情况下, N条记录的表重建索引的耗时
四、设计与优化思考
最后得到2个设计与优化目标
- 在有限的资源下, 如何提升各项指标
- 如何用更少的资源, 满足各项指标要求
前面说了, 本文主要聚焦在RAG场景对数据库的需求, 细节处则将重点放在向量搜索上.
所以下面的设计和优化思路都只考虑向量索引.
1、提升支持的数据体量
- 不改变原始值, 降低精度. 例如 float8 降到 float4 , 损失溢出边界值, 溢出值变更为无穷大或无穷小.
- 统计量化 SBQ. 采样若干条原始向量, 对每个维度进行聚集统计, 得到N个聚集点, 将原始值映射到最近的聚集点. 从而将每个维度量化了
log2(N) 个 bits - 残差量化 RaBitQ. 参考论文: https://arxiv.org/pdf/2405.12497
- 仅对前N个维度创建向量索引. 例如 Matryoshka embedding, 仅前N个维度有语义含义.
需要注意, 量化后, 需要做到对量化后的值进行排序和原始值排序结果对比的误差较小. 如果原始值发生变化, 可能改变导致语义改变, 如果原始元素有意义, 则不可以使用量化方法.
2、提升召回精度
- 使用原始向量值进行reranking, 解决量化带来的误差.
- 如果索引未存储原始向量, 回表reranking
- 如果索引存储了原始向量, 不回表reranking
- 仅对量化orderd的前N条, 使用原始向量值进行reranking
- 索引存储降精度向量(而非原始向量), 但比sbq、rabitq量化的精度更高. 权衡“存储空间、查询效率、召回精度”. 不回表, 使用降精度向量进行reranking
对于典型的hnsw和ivfflat索引, 调整参数可提升召回率
- hnsw:
- 构图时: 增加每个节点的邻居节点数、动态候选近邻列表数
- 查询时: 增加候选近邻列表数, 采用严格排序设置(使用原始向量重排).
- ivfflat
- 先写入数据, 然后创建索引
- 查询时: 增加中心点个数
3、提高向量查询效率
- CPU SIMD指令集, 一个指令处理多个值.
- 异步IO, 提升IO吞吐, 缩短读取索引/回表的IO耗时
- 优化裁剪算法, 尽早裁剪不需要搜索/计算的向量
- lazy compute, 仅在需要时计算向量距离
- zero memory copy, 降低内存拷贝耗时以及内存消耗
- 索引预热, 对于内存可存放下的向量索引特别有效, 可完全避免磁盘IO.
对于典型的hnsw和ivfflat索引, 调整参数可提升查询速度(但损失召回精度)
- hnsw:
- 构图时: 适当减少每个节点的邻居节点数
- 查询时: 减少候选近邻列表数, 采用松散排序设置(不使用原始向量重排). 更激进的裁剪, 减少需要搜索/计算的向量.
- ivfflat
4、提高混合查询效率
- 预过滤, 对于大量不满足条件的标量条件, 效果非常好, 可提起裁剪大量无效向量.
- 组合索引, 参考vexdb设计. 类似分区索引, 在标量字段分区, 根据落在分区中的记录条数对向量字段创建图索引或ivfflat倒排索引.
- 改变查询结构, 采用 RRF reorder .
- 创建3种类型的索引: 标量、全文检索、向量检索
- 每种条件使用一条查询, 并对查询结果按设定权重计算得分.
- UNION所有条件的结果, 去重, 并按得分对结果排序, 取出top-n
- 使用 reranking 模型排序, 取出top-k
5、提高写入效率
- 图索引的实时写入延迟较大, 因为写入对原图的结构由影响. 可以借鉴gin索引思路, 异步构图: 对新插入的记录写入pending list, 由autovacuum触发索引合并
- 查询时, 合并pending list和索引中搜索到的结果
- 仅在索引页子节点中存储量化后的结果, 减少索引大小提高写入效率
6、提高创建索引的速度
- 利用数据库并行特性, 并行创建索引
- 内存中构图
- 提高maintenance_work_mem内存设定
- 异步IO
- zero 反序列化, 可借鉴arrow的方式, 存储与内存中格式一致, 避免反复序列化和翻序列化带来的开销. 需存取大量时间时可能非常有效.
对于典型的hnsw和ivfflat索引, 调整参数可提升创建索引的速度(但损失召回精度)
- hnsw:
- 构图时: 提高maintenance_work_mem内存设定, 适当减少每个节点的邻居节点数, 减少动态候选近邻列表数
- ivfflat
- 构图时: 先写入数据, 然后创建索引. 减少中心点个数.
7、其他优化
8、瓶颈分析
- 每种优化方法能带来多大效果? 取决于瓶颈在哪。可在每一项优化目标的压测case执行时使用 perf 抓取统计信息, 进行代码分析得到瓶颈。
9、工具利用
后话
AI 搜索的需求最主要的来自RAG场景, 但AI 应用绝非只有RAG. 对数据库的需求也绝非只有向量搜索、混合搜索、图式搜索(这些通常代表的是RAG场景的需求). 真实的情况是: 数据库作为数据资产的存储介质, 如何产生数据价值! 所以分析能力也是其重要需求之一.