当前位置: 首页 > news >正文

pgvector语义检索踩坑:为什么加了 ORDER BY 反而查不到数据?

1.背景

最近在做一个agent项目,涉及到了pgvector向量数据库的语义检索检索。
碰到了这样的一个奇怪现象:数据库里明明有数据,但是什么也查不出来,我也没有用where对检索进行限制,只是做了order by;当去除order by后才能查出东西来
我执行的语句类似如下所示,这个语句很正常,就是根据传入的向量,到向量数据库中查询相似度最高的topK条记录并返回,可是查不出东西。

SELECTc.document_id   AS documentId,c.id            AS chunkId,c.content       AS content,d.title         AS title,d.url           AS url,(c.embedding <=> #{embedding}) AS distanceFROM kb_chunk cLEFT JOIN kb_document d ON c.document_id = d.idWHERE c.embedding IS NOT NULLORDER BY distanceLIMIT #{topK}

当去除order by后,即执行下面的sql才能查出东西(但是由于没有topK逻辑了,不符合需求,只能靠java对数据结构再做topK)

SELECTc.document_id   AS documentId,c.id            AS chunkId,c.content       AS content,d.title         AS title,d.url           AS url,(c.embedding <=> #{embedding}) AS distanceFROM kb_chunk cLEFT JOIN kb_document d ON c.document_id = d.idWHERE c.embedding IS NOT NULLLIMIT #{topK}

更反常的事来了,输入不同query进行查询的话结果不一样:
query=“重启” ✅ 能查出来
query=“你好,怎么用知识库检索?” ❌ 查不出来(返回 [])

2.排查过程

我做了几件“确认”:

2.1确认表里真的有embedding

select count(*) from kb_chunk; -- 2
select count(*) from kb_chunk where embedding is not null; -- 2

2.2确认向量维度一致

维度不一致会导致距离计算出问题。

SELECT vector_dims(embedding) AS dims, COUNT(*)
FROM kb_chunk
WHERE embedding IS NOT NULL
GROUP BY dims;

结果:dims=1024, count=2,同时在Java里打印query向量维度:也是1024。所以排除“维度不一致”。

2.3确认向量里没有 NaN/Infinity

如果embedding里出现NaN(非数字)或Infinity(无穷大),排序会乱。
在java中加入以下代码做调试,发现也不存在NaN或Infinity

var list = queryEmbedding.vectorAsList();
long badCount = list.stream().filter(v -> {double d = ((Number)v).doubleValue();return Double.isNaN(d) || Double.isInfinite(d);
}).count();
log.debug("query='{}' dim={}, badCount={}", query, list.size(), badCount);

发现真实原因

此时其实我能隐约感觉到会不会是我的数据数量太少的原因,于是做了以下验证查索引定义:

SELECT indexname, indexdef
FROM pg_indexes
WHERE tablename = 'kb_chunk';

发现了下面这条内容:

CREATE INDEX idx_kb_chunk_embedding_ivfflat
ON public.kb_chunk USING ivfflat (embedding vector_cosine_ops)
WITH (lists='100')

原来是因为向量索引(ivfflat)的lists太大 + probes太小,导致“空桶”!

2.1 原因剖析

向量数据库的查询并不是简单的“=”,而是“<=>”。当一定情况下会使用向量索引,这是是“近似检索”,它不保证一定能找出候选数据。

2.1.1 ivfflat的工作方式

ivfflat 可以把它想象成下面两步:

第一步:lists(分桶)
建索引时设置了:USING ivfflat ... WITH (lists = 100)
lists 的意思可以理解为把所有向量分成100个桶(list),每条向量会落到其中一个桶里。当数据量很大时(比如10万条),分成100个桶没问题,每个桶里都能有很多数据。但实际数据量是2条(因为是demo产品),这就会出现很夸张的情况:100个桶里,最多只有2个桶里有数据,剩下98个桶是空桶(桶里没有任何向量)。

第二步:probes(探测桶)
查询时数据库不会扫完100个桶,它会先判断“最可能相近”的几个桶,然后只在这些桶里找候选。这个“查几个桶”,就是probes:
probes 越小:越快,但越容易漏。
probes 越大:越慢,但越稳。
默认 probes 往往是 1(只看 1 个桶)。

为什么“重启”能查到数据,而“你好…”查不到?

这就是“空桶效应”:

query=“重启” 的向量,落到的“最相近桶”刚好是一个非空桶
→ probes 即使不大,也能在桶里找到那条向量 → 有结果

query=“你好,怎么用知识库检索?” 的向量,落到的“最相近桶”刚好是空桶
→ probes=10 只探测 10 个桶,但这 10 个桶恰好都空 → 候选集=0 → 返回 0 行

当把probes设为100时,相当于把所有桶都探测了一遍:
即使 query 先落到空桶,最终也会探测到那两个非空桶
→ 一定能捞到候选 → 就能返回结果。

为什么“去掉 ORDER BY”就正常?

因为去掉 ORDER BY embedding <=> query_vector 后,数据库不需要计算距离,也就不会走 ivfflat 向量索引,查询退化成普通的 “从表里随便拿几条数据” 的行为,所以它会稳定返回 LIMIT 的结果(只要表里有数据)。

避免踩坑

数据量很小的时候,不要把 lists 设很大(比如 N=2 还 lists=100)

如果必须用 ivfflat的话,让 probes 足够大(至少不远小于 lists)

或者直接把 lists 设小(例如 1~10)

可能的歧义

有人可能会问,既然是因为算了distance,触发了向量近似索引,可是在主句中也算了distance呀:

select ..., (c.embedding <=> #{embedding}) AS distance from kb_chunk

这其实涉及到了一些数据库的优化。如果加上 ORDER BY distance LIMIT k 后,数据库需要找出‘最相似的前 k 条’,这通常会触发向量索引(ivfflat)走近似检索路径;而没有 ORDER BY 时,数据库只需要随便返回 k 条记录,不必做‘全局最相似’的计算,也就没有那么大压力,因此不会走 ivfflat。

http://www.jsqmd.com/news/421455/

相关文章:

  • 2026年娱乐会所设备回收哪家靠谱? 口碑好效率高 覆盖多区域需求 - 深度智识库
  • 2026年天津Q50录取率比较高的国际高中名单与择校指南 - 品牌2025
  • 探头式超声粒度仪的定义与特点
  • Spaly复杂度分析
  • 三维晶体晶面生长动力学测定仪的应用领域
  • 2026年 佐敦油漆厂家推荐排行榜:佐敦底漆/环氧云铁中间漆/氟碳漆/环氧富锌底漆/核级环氧涂料,专业防护与长效耐久工业涂装解决方案 - 品牌企业推荐师(官方)
  • Cesium.SceneTransforms分析
  • 2026国内最新云石胶五大源头厂家实力排行榜:聚焦全屋健康,基于环保性能与市场口碑的权威推荐榜单 - 十大品牌榜
  • GitHub 10万星的OpenCode,正在悄悄改变程序员的工作流
  • 2026嘉兴工装装修公司推荐:从100家筛出的6家干货榜单 - 企师傅推荐官
  • 2026年驻车空调品牌推荐,主要有哪些在浙江制冷量高的生产厂家? - 睿易优选
  • SpringBoot整合秘笈:让Mybatis用上Calcite,实现统一SQL查询
  • 生成式人工智能渗透进IBM 工程生命周期管理/应用生命周期管理和研发领域
  • 基于MATLAB的简单卷积神经网络(CNN)实现代码
  • vLLM v0.16.0 重磅发布:吞吐量提升30%,异步调度+流水线并行全面整合
  • 2026年气体检测与扬尘检测采购平台推荐:采购量大/供应商多的热门B2B平台盘点 - 品牌推荐大师1
  • Geovia Surpac、Whittle 与 MineSched 完全指南
  • 北京小程序开发服务指南:2026年企业数字化转型的定制之选 - 品牌2025
  • 2026年一体成型/贴片/功率/大电流/共模电感厂家推荐榜:适配电源管理、汽车电子与通信模块多场景应用 - 品牌推荐官
  • AI视频制作大师课:从脚
  • 汽车配件海外营销代运营:推荐几家擅长TikTok与ins代运营的服务商 - 品牌2025
  • 2026年AI仓储软件(WMS)推荐:高效管理解决方案 - 品牌排行榜
  • 北京小程序开发深度解析:2026年定制化服务如何赋能行业转型 - 品牌2025
  • 别再踩坑!如何选择短信接口服务商?可以从这几点判断 - Qqinqin
  • 上海B2B企业出海营销服务商推荐:涵盖Linkedin海外营销推广与Google代运营 - 品牌2025
  • 偌米品牌知名度高吗? - 中媒介
  • 2026年仓储软件(WMS)值得推荐的实用参考 - 品牌排行榜
  • 北京小程序开发攻略:2026年企业如何锁定优质定制服务商 - 品牌2025
  • 2026年全国二手中央空调回收哪家靠谱? 覆盖多区域专业处置更放心 - 深度智识库
  • 2026精选|四大全国知名的GEO优化公司推荐,AI时代获客不踩坑 - 品牌推荐大师1