在混合搜索系统的实际落地过程中,选型只是第一步,真正决定项目成败的,往往是工程实践层面的细节积累。
系统上线后的稳定运维,开发者绕不开这几个核心问题:怎么写查询、混合检索怎么调、性能怎么测、出问题怎么排查。本文将围绕这些关键环节,梳理一套可落地的向量查询调优最佳实践,帮助开发者少走弯路、快速上手。
立即试用 OceanBase 企业版,体验国产数据库能力
查询与调优
查询语句怎么写、Hint 怎么用、召回和延迟的旋钮怎么拧------这一章决定了你的 QPS 报告好不好看。
1.1. 基础查询
不带标量过滤的向量近似查询(approximate nearest neighbor search)写法:
SELECT id, cosine_distance(embedding, @query_vector) AS distance
FROM htl_image_recall
ORDER BY distance APPROXIMATE
LIMIT 100;
APPROXIMATE 必须写(简写 APPROX 也行)。不写就走全表精确计算,不会用向量索引。
1.2. 混合查询
带标量过滤条件的向量近似查询称为混合查询(hybrid search),以下是 geohash 过滤 + 向量检索的写法:
SELECT id, picturename, cosine_distance(picturevector, @query_vector) AS distance
FROM htl_image_recall
WHERE geohash IN('gcq2j', 'u10kk', 'wvkut')
ORDER BY distance APPROXIMATE
LIMIT 100;
OceanBase 4.3.5 起混合检索会自动选算法:标量过滤性好就走前过滤(pre-filter,先用标量索引筛,再向量搜),过滤性差就走迭代式过滤(post-filter,向量搜的过程中逐步套标量条件)。在过滤字段上最好都建好索引。

添加图片注释,不超过 140 字(可选)
1.3. Hint 控制策略
知道过滤特征的话,用 hint 指定比依赖自适应更稳。4.6.0 起推荐使用 VECTOR_INDEX hint,可同时指定向量索引和过滤路径:
-- 4.6.0+ 推荐写法:指定向量索引 + 前过滤(pre-filter),并指定标量索引
SELECT /*+ VECTOR_INDEX(t idx_vec PRE_FILTER) index(t idx_geohash) */ id,
cosine_distance(picturevector, @query_vector) AS distance
FROM htl_image_recall t
WHERE geohash IN('gcq2j', 'u10kk')
ORDERBY distance APPROXIMATE LIMIT 100;
-- 4.6.0+ 推荐写法:指定向量索引 + 迭代式过滤(post-filter)
SELECT /*+ VECTOR_INDEX(t idx_vec POST_FILTER) */ id,
cosine_distance(picturevector, @query_vector) AS distance
FROM htl_image_recall t
WHERE geohash IN('gcq2j', 'u10kk')
ORDERBY distance APPROXIMATE LIMIT 100;
旧版本(4.6.0 以前)用 index() hint 也能控制:指定标量索引名走前过滤,指定向量索引名走迭代式过滤。
1.4. 召回与延迟的权衡
ef_search(HNSW 系列)和 nprobes(IVF)是核心旋钮。
HNSW 系列(768 维,千万级,目标 Recall ≈ 0.95):

添加图片注释,不超过 140 字(可选)
IVF 单分区(千万级,目标 Recall ≈ 0.90):

添加图片注释,不超过 140 字(可选)
IVF 分区表(亿级)------各分区独立查询后汇总 rerank,实际召回高于单分区,可以用更低的 nprobes:

添加图片注释,不超过 140 字(可选)
总的来说,ef_search 和 nprobes,可以用性能换取召回,或者反过来。但如果将这两个参数调到很大都无法满足召回,或者性能太差,可以再调整索引构建参数重建索引,用构建性能换取查询性能。
1.5. 用 EXPLAIN 检查向量索引、分区裁剪与过滤策略
EXPLAIN 可以看出:走了向量索引没有(不是全表扫)、分区裁剪生效没有(partitions 字段应只含少量分区)、混合查询用了什么算法(前过滤还是迭代式过滤)。
EXPLAIN EXTENDED SELECT id,
cosine_distance(picturevector, @query_vector) AS distance
FROM htl_image_recall
WHERE geohash = 'gcq2j'
ORDER BY distance APPROXIMATE LIMIT 100;
性能验证
怎么测才不踩坑------压测姿势不对,得出的结论会误导决策。
2.1. 测试方法
四个核心指标:QPS、平均 RT、P95/P99 RT、召回率。

添加图片注释,不超过 140 字(可选)
召回率测试:准备 100 个以上查询向量,分别跑精确搜索和近似搜索,对比结果:
-- 精确搜索(ground truth)
SELECT /*+ PARALLEL(32) */ id,
cosine_distance(picturevector, @query_vector) AS distance
FROM htl_image_recall
WHERE geohash IN('gcq2j', 'u10kk')
ORDERBY distance LIMIT 100;
-- 近似搜索
SELECT id,
cosine_distance(picturevector, @query_vector) AS distance
FROM htl_image_recall
WHERE geohash IN('gcq2j', 'u10kk')
ORDERBY distance APPROXIMATE LIMIT 100;
注意:压测时最好进行合并(major freeze)和预热,减小回表和读盘对查询性能的影响。
2.2. 实测性能参考
百万级 768 维(m=16, ef_construction=200, Top100, ef_search=240):

添加图片注释,不超过 140 字(可选)
千万级 768 维(m=32, ef_construction=400, Top100):

添加图片注释,不超过 140 字(可选)
4.5 亿 384 维混合查询(HNSW_SQ, m=32, 45 分区,20 并发):

添加图片注释,不超过 140 字(可选)
向量查询性能问题排查手册
出问题时不要乱调参数,按这张表的"现象 → 原因 → 动作"走,90% 的问题能在 10 分钟内定位。
以下是大规模向量场景最常见的性能问题及排查方法:

添加图片注释,不超过 140 字(可选)

添加图片注释,不超过 140 字(可选)
立即试用 OceanBase 企业版,体验国产数据库能力