You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Supabase进行pg vector搜索时数据量过大无结果的求助

解决Supabase中pgvector向量搜索无结果的问题
  • 检查索引与查询操作符的匹配性
    你的HNSW索引使用了vector_cosine_ops(余弦距离算子),但查询中却用<=>(L2距离算子)计算相似度,两者不匹配会导致数据库无法利用向量索引,只能全表扫描,效率低下且可能漏判结果。
    修正方式:改用余弦距离的<#>算子,调整函数中的SQL:

    CREATE OR REPLACE FUNCTION "public"."match_documents"("query_embedding" "public"."vector", "match_threshold" double precision, "match_count" integer, "p_userid" "uuid") RETURNS TABLE("id" "text", "chunktext" "text", "sourceId" "text", "similarity" double precision, "document" "jsonb")
        LANGUAGE "sql" STABLE
        AS $$
    SELECT 
      documents.id, 
      documents."chunkText", 
      documents."sourceId",
      1 - (documents.embedding <#> query_embedding) AS similarity, 
      documents.document 
    FROM documents 
    WHERE 
      1 - (documents.embedding <#> query_embedding) > match_threshold 
      AND documents."userId" = p_userid
    ORDER BY similarity DESC 
    LIMIT match_count;
    $$;
    
  • 验证向量索引是否被正确调用
    用EXPLAIN ANALYZE执行查询(替换实际参数),查看执行计划是否用到documents_embedding_idx:

    EXPLAIN ANALYZE SELECT * FROM match_documents('你的查询向量', 0.7, 10, '用户UUID');
    

    如果未使用向量索引,可尝试直接用余弦距离排序(等价于相似度降序),帮助数据库识别索引:

    SELECT 
      id, "chunkText", "sourceId",
      1 - (embedding <#> '你的查询向量') AS similarity, document
    FROM documents 
    WHERE "userId" = '用户UUID'
    ORDER BY embedding <#> '你的查询向量'
    LIMIT 10;
    
  • 调整HNSW索引参数提升召回率
    默认的HNSW参数(m=16, ef_construction=100)对5万条数据可能不够,可重新创建索引优化参数:

    DROP INDEX IF EXISTS "documents_embedding_idx";
    CREATE INDEX "documents_embedding_idx" ON "public"."documents" USING "hnsw" ("embedding" "public"."vector_cosine_ops") WITH (m=32, ef_construction=200);
    

    m越大索引精度越高但占用空间越大,ef_construction越大构建时间越长但召回率越好,可根据实际情况调整。

  • 排查阈值设置与向量归一化

    • 降低match_threshold测试,比如从0.9降到0.7,确认是否存在符合低阈值的结果;
    • 确保所有存储的embedding和查询的query_embedding都已归一化为单位向量(余弦相似度计算的前提),未归一化会导致相似度计算失真。
  • 优化用户过滤逻辑
    先通过userId过滤出用户的所有文档,再在子集内做向量搜索,减少向量计算的范围:

    CREATE OR REPLACE FUNCTION "public"."match_documents"("query_embedding" "public"."vector", "match_threshold" double precision, "match_count" integer, "p_userid" "uuid") RETURNS TABLE("id" "text", "chunktext" "text", "sourceId" "text", "similarity" double precision, "document" "jsonb")
        LANGUAGE "sql" STABLE
        AS $$
    SELECT 
      filtered.id, 
      filtered."chunkText", 
      filtered."sourceId",
      1 - (filtered.embedding <#> query_embedding) AS similarity, 
      filtered.document 
    FROM (SELECT * FROM documents WHERE "userId" = p_userid) AS filtered
    WHERE 
      1 - (filtered.embedding <#> query_embedding) > match_threshold 
    ORDER BY similarity DESC 
    LIMIT match_count;
    $$;
    

    这种方式会先利用documents_userId_idx过滤数据,再在小范围内计算向量相似度,提升效率和召回率。

  • 避免参数与列名冲突
    原函数中参数名userid与列名"userId"易产生歧义(PostgreSQL对大小写敏感,未加引号的标识符会转为小写),建议将参数名改为p_userid之类的命名,避免解析错误。

内容的提问来源于stack exchange,提问作者Shamoon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 13:23:24