向量检索最佳实践:原理、相似度度量与ANN索引选型

举报
数据库小学妹 发表于 2026/10/13 16:04:54 2026/10/13
【摘要】 一篇讲清向量检索的原理与完整链路:从Embedding、相似度度量、ANN索引到混合检索,附度量方式对比表与主流索引适用边界,帮你搞懂"为什么结果不按字面匹配却对了"。

大家好,我是数据库小学妹👋 我踩过的坑,你别再踩。

刚转行那会儿,我在知识库里搜"怎么申请年假",文档标题写的是"休假流程说明",关键词一个都没对上,搜了个空。当时我以为是自己关键词没选好,后来我才慢慢明白,问题不在我,在检索方式本身。关键词检索要的是字面对上,而人问问题时,用的是意思。

向量检索,是把文本、图片这些内容转成高维空间里的向量,用距离或夹角衡量"意思像不像",返回语义最接近的若干条结果。哪怕查询里一个原词都没出现,它也能召回意思相近的内容。这篇不堆术语,把它的完整链路从Embedding到ANN,一步步讲清楚。

一、关键词检索卡在哪

先说清楚它解决什么。传统关键词检索靠倒排索引,把词和文档对起来,查询时匹配词。它有两个好处:字面匹配准,可解释性强,所以到现在还是检索系统的基础。但它有两个天生的短板。

一是同义不同词。“数据库备份"和"数据快照”,字面毫无重叠,倒排索引匹配不上,可人和AI都知道这俩说的是一件事。

二是语义模糊。用户搜一句口语化的问题,词和词之间的真实意图,字面上表达不出来。

向量检索的思路换了个方向:不匹配词,匹配意思。把词义压进一个向量里,意思近的,向量距离就小。

二、完整链路:四步走

把一件内容变成"可被语义检索"的东西,要走四步。

内容 ──①Embedding──▶ 向量 ──②相似度度量──▶ 距离/夹角
                          ──③索引(ANN)──▶ 快速候选集
查询 ──④查询向量化──▶ 同空间向量 ──▶ 检索Top-K

第一步,Embedding(向量嵌入)。 用模型把文本、图片、音频编码成一个固定维度的稠密向量,比如768维、1024维。文字怎么变数字?早期有Word2Vec、GloVe这类词向量,现在主流是BERT、bge这类句子级模型。同一个模型产出的向量,才会落在同一个空间里,能互相比较。

第二步,相似度度量。 有了向量,得有个标准衡量"谁离谁近"。这一步看似简单,选错了后面全歪。

第三步,建索引。 百万级向量不可能逐个比,得建ANN索引把搜索范围缩小。

第四步,查询向量化。 用户查询必须用同一个模型转成向量,才能和库里向量比。这里最容易出的错,是库用A模型、查询用B模型,两个空间的向量比出来毫无意义。

图1 把内容变成"可被语义检索",走这四步

三、相似度度量怎么选

四种常用度量,各有各的脾气。

度量方式 计算的是什么 取值范围 典型场景
余弦相似度 两个向量的夹角余弦 -1到1 文本语义检索,只看方向不看长度
欧氏距离 空间中两点的直线距离 0到正无穷 图像检索、推荐系统
内积 两个向量的点积 负无穷到正无穷 向量已归一化时,等价余弦
海明距离 两个二值向量不同的位数 0到向量维度 大规模二值向量检索

选择逻辑其实不复杂。文本检索一般用余弦,因为它只看向量方向,不受文本长度影响。图像、推荐常用欧氏距离。归一化之后用内积还能省一次计算,这也是很多工程实践在第一步Embedding时就顺手normalize的原因。

归一化决定了内积和余弦是否等价。做了归一化,两者可以互换;不做归一化,就得老老实实选余弦。前提是写入和查询保持一致。

度量方式定了,向量之间就能比出谁近谁远。但库里动辄几十上百万条向量,一条条算距离,查询等不起。下一步,就得靠索引把搜索范围缩下来。

四、ANN索引:用一点召回率换大幅提速

先说清为什么非建索引不可。精确检索(KNN)每次都拿查询向量和全量向量算一遍距离,结果100%准,但数据一大就慢。ANN(近似最近邻)换个思路:用一个结构,把"明显不可能最近的"先排除掉,只在候选集里精算。代价是可能漏掉极个别真正最近的,换来的是数量级的提速。

主流ANN索引,思路可以分几类:

索引类型 代表算法 核心思路 适用边界
基于图 HNSW、NSG 用邻居关系建图,从入口点逐层逼近 召回与速度均衡,生产最常用
基于聚类倒排 IVF、IVF-PQ 先聚类分桶,查询只扫最近几个桶 大规模、可用PQ压缩
基于量化 PQ、二值化 把高维向量压成短码,快速估算距离 内存受限场景
基于哈希 LSH 让相似向量更易落入同一桶 特定度量下有优势,通用性弱
磁盘图索引 DiskANN 图索引落到磁盘,突破内存限制 超大规模、内存吃紧

图2 主流 ANN 索引按思路分五类

生产环境里,HNSW是最常见的选择,因为它在召回率和延迟之间的平衡做得不错,参数也相对好调。它的三个关键参数,这里只说结论:M和ef_construction管索引质量,ef_search管查询时的召回与延迟,调参就是在这几个旋钮上找平衡点。

一段最小的建索引和查询长这样:

-- 建HNSW向量索引
CREATE INDEX idx_doc_vec ON doc_embedding
    USING hnsw (embedding vector_cosine_ops)
    WITH (m = 16, ef_construction = 200);

-- 检索:向量距离 + 标量过滤在同一条SQL里
SELECT id, title,
       1 - (embedding <=> :q) AS sim
FROM doc_embedding
WHERE category = 'faq'
ORDER BY embedding <=> :q
LIMIT 10;

这段写法里藏着一个关键判断:向量检索和标量过滤能不能在同一次查询里完成。如果你的场景里,向量和业务数据强关联,要一起过滤和排序,那向量库和业务库一旦分开,就只能先召回、再过滤、再拼装,过滤条件一多,结果就容易凑不满。这也是为什么越来越多的关系型数据库把向量能力做进内核。金仓KES Vector做的事,就是把链路里的第三步(ANN索引)和第四步(查询向量化与检索)直接嵌进数据库内核,让你不用在向量库和业务库之间来回倒数据。

五、召回、延迟、更新:三个方向拉不满

很多人以为ANN参数调得越高越好。向量检索本质上是一次权衡,而且很难两头都占。

想保召回率,就把ef_search调大、用图索引,适合答案漏了代价高的场景,比如合规检索。想保延迟,就把候选池调小、用更简单的索引,服务高并发在线问答。数据更新频繁的时候,还要优先选重建代价低的索引,别死磕对写入不友好的结构。像KES Vector的向量索引,建好之后依然支持新向量的插入和删除,不用重建,对写入频繁的场景就比较友好。这三个方向基本没法同时拉满。

专业库在纯向量高并发下的极限性能更好;把向量融进关系库内核的路线(比如KES Vector),在"向量和业务数据要一起用"的场景里链路更短,一个库管住关系、文档、向量、GIS、时序,省掉跨库同步,也少维护一套系统。选哪个,取决于你的数据之间要不要互相看。

六、它最适合哪几类场景

向量检索不是万能的,但在这几类场景里几乎是标配:

企业知识库问答(把文档切片存向量,按语义召回)、语义搜索(理解意图,不卡关键词)、以图搜图(图片转向量做相似匹配)、推荐召回(用户和内容落在同一空间算相似度)、RAG(先向量检索找相关片段,再交给大模型生成答案,缓解幻觉和知识过时)。

共同点都是:数据本身是文本或多媒体,语义相似比字面匹配更重要。

七、什么时候会失效,什么时候用不上

知道边界,比知道能力更重要。

需要精确匹配的地方别用向量。 查订单号、身份证、金额区间,这些要的是"精确等于",向量检索给的是"近似相似",用错地方反而误事。这类还是走标量索引和条件查询。好在这种精确查询和语义检索不必分家:把向量做进内核的关系库(比如KES Vector),一个走标量索引、一个走向量索引,同一份数据、同一个事务,不用为加一层语义检索再单独引一套系统。

数据太少,用不上它。 几百条数据,暴力比对就够了,上ANN索引纯属给自己加复杂度。

Embedding模型选错,后面全白费。 模型和你的语种、领域不匹配,向量本身就表达不准,索引再精细也捞不回来。选型时先拿真实数据验证模型的语义表达能力。

查询和库用了不同模型,比较无意义。 这条前面提过,但踩的人最多,向量维度对上了、空间对不上,结果就是乱的。

八、避坑清单

度量怎么选、索引怎么分、维度怎么定,这些边界上面都说得差不多了。再补三条我踩过、也见别人踩过的坑,看着都不大,翻车的时候却挺让人头疼。

第一,归一化这件事,要么全程做,要么全程不做。我见过的坑里,至少有一半来自写入时归一化了、查询时忘了,余弦和内积混着用,结果忽好忽坏。

第二,别拿单次检索的"感觉"当评测。固定一批测试集,算召回率,才看得见参数调整到底有没有用。

第三,这条是我自己交的学费。我一开始以为"向量维度越高、表达越准",给一个短文本场景上了1024维模型,结果存储和检索成本上去了,效果和768维几乎没差别。维度不是越高越好,得和你的内容长度、颗粒度匹配。一般短文本768维够用,长文档或专业领域可以到1024维,再往上收益递减就很明显了。

这三条说到底是同一件事:参数和选型都得跟你的真实数据对齐,脱离数据谈好坏,没什么意义。

九、小结

向量检索的链路就四步:Embedding把意思变向量、相似度度量定规矩、ANN索引提速度、查询向量化保证同空间。理解这四步,参数和选型就不会迷路。

从工程落地上看,把向量能力放进关系型数据库内核(例如KES Vector),向量和业务数据在一个事务、一条SQL里处理,链路短、少维护一套系统。对已经在跑关系库、想低成本加语义检索能力的团队,这条路值得放进评估清单。

你被哪一步坑过,是Embedding选型、度量方式,还是索引参数?评论区说说,我挑几个典型的在下篇拆。

我是数据库小学妹,帮你少走弯路少踩坑,咱们下篇见👋

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。