Querying
原文链接:https://www.yuque.com/yangguangfanxing/nmhuv1/rwgt2m3mdq4xzww1

Recap

现代应用需要向量数据库 = 向量存储 + 语义搜索
插入向量:
- 创建嵌入向量
- 将
存入专用数据库(附带属性)
查询数据: 3. 将查询嵌入为向量 4. 找到
的最近邻

RDBMS 与 VDBMS 对比
不同需求 → 不同设计
| 维度 | 传统数据库 (RDBMS) | 向量数据库 (VDBMS) |
|---|---|---|
| 数据 | 记录 (Records) | 向量 (Vectors) |
| 查询 | 关系代数 | 最近邻 + 过滤 |
| 高级查询 | JOIN, GROUP, FK, 游标 | 无 |
| 更新 | 部分记录、多条记录 | 整体向量、插入/删除/替换 |
| 一致性 | 强一致 + 事务 | 最终一致,可调 |
| 索引更新 | 快 | 慢 |
| 存储 | 行/列存储, LSM | 向量是不透明 blob |
| 硬件/成本 | 均匀、适中 | 多样、昂贵(GPU) |
| 架构 | 更单体化 | 更分离化 |
关键挑战: 大向量、无结构、更新慢

Querying



问题定义
- 已知:查询向量
- 目标:找到"某些"在
附近的向量
三个核心问题
- 什么是"附近"? → 相似度分数
- 哪些向量? → 各种查询类型
- 何时返回? → 尽可能快

距离 / 相似度评分
给定向量 ,计算表示相似性/距离的数值。
| 名称 | 函数 | 值域 |
|---|---|---|
| 欧氏距离 (Euclidean) | ||
| 内积 (Inner Product) / MIPS | ||
| 余弦相似度 (Cosine) | ||
| 马氏距离 (Mahalanobis) | ||
| 汉明距离 (Hamming) | ||
| 曼哈顿距离 (Manhattan) |
注: 内积和余弦是相似度(值越大越近),需反转才能用作距离。
MIPS = Maximum Inner Product Search。

相似度转距离
将相似度分数 反转的方法:
简单反转: 使用
余弦距离:
内积转换(增加一维):
- Sigmoid 变换(数值不稳定,不常用):


kNN 查询(核心查询)
找到 个最近邻。
形式化定义:
返回 满足:
pgvector 示例:
SELECT * FROM items
ORDER BY vec <-> '[1,6.4,-2.1]'
LIMIT 5;
范围查询(Range Query)
返回指定半径 内的所有向量:
pgvector 示例:
SELECT * FROM items
WHERE vec <-> '[1,6.4,-2.1]' < 4;不常用,因为应用中难以确定合适的 。

谓词查询(Predicated Queries)
别名: 属性过滤、混合查询(Hybrid Queries)
定义: kNN/范围查询 + 对关联属性的谓词过滤。
Pinecone 示例:
index.query(
namespace="products",
vector=[0.81, 0.46, 0.41, 0.64, 0.11],
filter={
"price": {"$lt": 100},
"color": {"$eq": "green"}
},
top_k=3,
include_metadata=True
)
核心问题
ANN (Approximate Nearest Neighbors) 索引与属性索引不兼容!
预过滤(Prefiltering): 先按属性过滤 → 再 kNN
后过滤(Postfiltering): 先 kNN → 再按属性过滤


三种过滤策略
预过滤 + 全表扫描
后过滤 + 增大
单阶段扫描(Holy Grail)

示例实现
| 方法 | 说明 | 产品 |
|---|---|---|
| Block-first (预过滤) | 构建谓词位图,kNN 时使用 | Milvus, AnalyticsDB-V |
| Pre-partition (预过滤) | 按属性范围预分区,查询多个分区合并 | Milvus |
| Visit-first (单阶段) | 从最近邻开始,逐步添加满足过滤条件的下一邻居 | Timescale (pgvectorscale / StreamingDiskANN) |

多向量查询(Multi-Vector Queries)
别名: 混合搜索、多模态搜索
场景:
- 同时在多个向量空间搜索
- 单个实体有多个向量(如文本 + 图像、多角度人脸、多尺度编码)
- 使用多个嵌入模型

朴素方法
- 执行
次 kNN 搜索 → 得到
个向量
- 合并分数(最小值、加权平均、最大值、学习组合等)
- 选择 top
问题: 分数合并方式可能导致漏掉真正的最近邻。

经典 top-k 算法的问题
需要"获取下一候选"操作 → 大多数向量索引不支持!

高级方法
向量融合(Vector Fusion)
迭代合并(Milvus)
MUST [Wang, ICDE'24] — 最新研究成果
Timescale 流式检索索引 — 最新研究成果

重排序(Reranking)
许多 VDBMS 提供查询后的重排序步骤。
流程:
- 获取 kNN 结果集
- 应用重排序模型重新排序
原因:
- 距离分数衡量的是相似性,而非相关性
- 近似索引引入误差
- 重排序可以使用更复杂的模型
- 可以引入上下文信息
效果示意:
排序前:a b c d e f g h i j
↓ 重排序模型
排序后:c j b g i d a h e f
精确 kNN 很慢!
暴力搜索:
- 对所有
计算
,再排序/用优先队列
- 时间复杂度:
top-k 时间
- 支持精确 kNN、范围查询、谓词查询等所有类型
解决方案:近似最近邻搜索(ANNS)
ANNS 索引的权衡
| 好处 | 代价 |
|---|---|
| 搜索更快✅ | 准确度降低❌ |
| - | 更多内存❌ |
| - | 更慢的更新❌ |

示例:基于聚类的索引
- 构建: 聚类向量,关联到最近质心
- 查询: 找到离
最近的质心,搜索其列表
- 误差:
在边缘时可能漏掉更近的邻居