pgvector 是 PostgreSQL 的一个扩展,用于支持向量相似性搜索(如嵌入向量的余弦相似度、内积等)
pgvector 是 PostgreSQL 的一个扩展用于支持向量相似性搜索如嵌入向量的余弦相似度、内积等它本身不是 Redis 相关组件也不属于 Redis 生态而 Redis 是独立的内存数据库其向量搜索能力由Redis Stack含 RedisSearch 模块提供支持向量相似性搜索通过FT.SEARCHVECTOR字段。目前✅pgvector仅适用于 PostgreSQL无官方异步客户端但可通过异步 PostgreSQL 客户端如 Python 的asyncpg配合使用 pgvector 功能。✅Redis 官方异步客户端Redis 官方推荐的 Python 异步客户端是redis-py自 v4.0 原生支持async/await使用redis.Redis(..., decode_responses..., protocol3)配合await即可异步操作Node.js 官方客户端为redisv4完全基于 Promise/async。❌不存在名为 “pgvector Redis” 的官方项目或联合客户端——这是常见误解二者分属不同数据库系统不可混用。✅ 正确技术选型建议若需向量检索 关系型强一致性 → 用 PostgreSQL pgvector asyncpg若需高吞吐、低延迟向量近邻搜索 缓存一体化 → 用 Redis Stack 官方异步客户端如redis-py示例Python 使用 asyncpg pgvectorimportasyncpgasyncdefsearch_similar(conn,embedding:list[float],top_k5):returnawaitconn.fetch(SELECT id, 1 - (embedding $1) AS similarity FROM items ORDER BY embedding $1 LIMIT $2,embedding,top_k)示例Python 使用 redis-py 异步客户端importredis.asyncioasredis rredis.Redis(hostlocalhost,port6379,decode_responsesFalse)awaitr.hset(vec:1,mapping{$:embedding_bytes})# 存储向量需编码为 bytesresultsawaitr.ft(idx).search(Query(*[KNN 5 vector $B]).return_fields(id).dialect(2),{B:embedding_bytes})注意Redis 向量字段需为BLOBBYTES且需提前创建带VECTOR字段的索引pgvector 则直接在vector类型列上建IVFFLAT或HNSW索引。在 PostgreSQL 中pgvector 自 v0.7.02023年10月发布起正式支持HNSWHierarchical Navigable Small World索引这是目前最主流的近似最近邻ANN索引类型相比 IVFFLAT 具有更好的查询精度和更稳定的性能尤其在高维、小数据集场景。⚠️ 注意前提PostgreSQL ≥ 14推荐 15pgvector ≥ 0.7.0强烈建议使用最新稳定版如0.7.4HNSW 索引不支持并行构建CREATE INDEX ... PARALLEL但查询可受益于 PostgreSQL 的并行执行计划需正确配置且满足条件✅ 一、创建 HNSW 索引标准语法-- 假设表 items 有一列 embedding 类型为 vector(1536)CREATEINDEXONitemsUSINGhnsw(embedding vector_cosine_ops)-- 或 vector_l2_ops / vector_ip_opsWITH(m16,ef_construction64); 参数说明参数含义推荐值备注m每个节点的最大连接数影响图连通性与内存16默认或32~64高精度/大数据集值越大精度越高内存/构建时间上升ef_construction构建时的动态候选集大小64默认或100~200值越大索引质量越高构建越慢vector_cosine_ops使用余弦相似度对应1 - cosine_distance✅ 最常用适合归一化嵌入其他vector_l2_ops欧氏距离、vector_ip_ops内积等价于余弦当向量已归一化 查询时自动使用该操作符族无需额外指定。✅ 二、启用并行查询非并行索引构建而是并行执行查询计划HNSW 索引本身不可并行构建CREATE INDEX ... WITH (parallel N)不被支持但 PostgreSQL 可对包含 HNSW 查询的复杂查询如 JOIN、FILTER、LIMIT ORDER BY启用并行执行计划前提是✅max_parallel_workers_per_gather 0默认为 2✅parallel_setup_cost和parallel_tuple_cost设置合理默认即可✅ 查询中存在可并行的子节点如大表顺序扫描 HNSW 过滤后排序✅关键限制ORDER BY embedding ? LIMIT N这类纯向量 KNN 查询无法并行因 HNSW 扫描是单线程导航图但以下场景可触发并行对结果再 JOIN 其他大表WHERE 条件过滤大量行后再向量排序使用 CTE 或子查询包装 KNN 结果并进一步聚合✅ 示例可触发并行的混合查询-- 假设 items 表有 category 字段且 category 上有普通 B-tree 索引EXPLAIN(ANALYZE,VERBOSE)SELECTi.id,i.title,1-(i.embedding[0.1,0.2,...])ASscoreFROMitems iWHEREi.categorytech-- 可走索引扫描产生多块 → 可并行ORDERBYi.embedding[0.1,0.2,...]LIMIT10;→ 若category tech匹配大量行PostgreSQL 可能并行扫描这些块再各自做 HNSW 近邻计算注意每个 worker 仍独立执行 HNSW 导航非共享图。 强制启用并行调试用SETmax_parallel_workers_per_gather4;SETmin_parallel_table_scan_size0;✅ 三、验证与调优建议查看索引类型SELECTindexname,indexdefFROMpg_indexesWHEREtablenameitems;-- 应含 USING hnsw查看查询执行计划是否并行EXPLAIN(ANALYZE,BUFFERS)SELECT...;-- 观察是否有 Workers Launched: 2 字样监控 HNSW 性能pg_stat_all_indexes中idx_scan统计 HNSW 索引使用频次使用EXPLAIN ANALYZE关注Index Scan using ... hnsw耗时及Buffers使用⚠️ 注意事项HNSW 索引写入开销显著高于 IVFFLAT插入/更新更慢适合读多写少场景。VACUUM对 HNSW 索引无效它不依赖 FSM但需定期VACUUM主表。不支持CONCURRENTLY创建会报错需在低峰期执行。✅ 四、完整示例建表 HNSW 索引 查询-- 1. 启用扩展CREATEEXTENSIONIFNOTEXISTSvector;-- 2. 建表示例CREATETABLEitems(idSERIALPRIMARYKEY,titleTEXT,embedding VECTOR(1536));-- 3. 创建 HNSW 索引余弦相似度CREATEINDEXONitemsUSINGhnsw(embedding vector_cosine_ops)WITH(m32,ef_construction128);-- 4. 查询返回最相似的 5 个按相似度降序SELECTid,1-(embedding[0.1,0.2,0.3])AScosine_similarityFROMitemsORDERBYembedding[0.1,0.2,0.3]LIMIT5;