pgvector 批量写入与更新
向 pgvector 大表灌数据时,逐条 INSERT 是最慢的路径。提速手段有三类:用 COPY 做批量导入,速度最快;用批量 INSERT 配合批量提交减少往返(Python 侧可用 psycopg 的批量执行接口或 copy 接口);以及先灌数据、后建 ANN 索引——索引维护会显著拖慢写入。更新既有向量时按主键做 UPSERT,避免「先查再写」在并发下产生竞态。
基本信息
| 最快方式 | COPY 批量导入 |
|---|---|
| 常规方式 | 批量 INSERT 配合批量提交 |
| 建索引时机 | 先灌数据,后建 ANN 索引 |
| 更新方式 | UPSERT,INSERT 加 ON CONFLICT DO UPDATE |
| 事务策略 | 批量提交,避免单条提交 |
| 向量格式 | 方括号包裹的浮点数组文本 |
典型使用场景
- 首次全量灌库,追求最短窗口
- 换 embedding 模型后重新灌向量
- 每日增量同步新文档切片
- 修复性重灌某一批切分错误的数据
- 批量更新 payload 字段而不动向量
批量 UPSERT
批量 UPSERT
INSERT INTO kb_chunks (id, doc_id, content, embedding)
VALUES ($1, $2, $3, $4)
ON CONFLICT (id) DO UPDATE
SET content = EXCLUDED.content,
embedding = EXCLUDED.embedding; -- 按主键更新,避免先查再写
-- 批量灌库时把多条 VALUES 合并提交,减少往返次数写入方式对照
| 方式 | 速度 | 适用 |
|---|---|---|
| COPY | 最快 | 首次全量灌库、离线批量任务 |
| 批量 INSERT | 快 | 常规增量写入 |
| 逐条 INSERT | 慢 | 少量修补 |
| UPSERT | 取决于命中路径 | 按主键更新已有行 |
建索引会拖慢写入:大批量灌库的常规做法是先灌数据、后建 ANN 索引,建完再让统计信息更新,查询计划才准确。
单条提交会让每次写入都等一次持久化:批量灌库应使用批量事务,或按官方说明临时调整持久化策略,同时评估崩溃时的数据风险。
灌库前先验证一行:确认向量列的类型与维度、字段顺序都符合预期,否则类型不符会在整批写入时才报错,白白浪费窗口。
批次大小要实测确定:批次过大容易产生长事务与锁等待,过小则往返次数太多;按每批几千到几万行试跑,用实测速度决定。
批量写入要监控失败批次:失败的批次若被静默跳过,最终条数与预期不一致,且很难在事后定位缺了哪一批。