在向量数据库性能优化的前沿,构建大规模向量索引的效率是决定其能否投入生产的关键瓶颈。传统的 pgvector 扩展在处理亿级数据时,往往面临构建时间长、内存消耗巨大的挑战。本文将深入剖析 VectorChord 1.0 如何通过一系列创新优化,在PostgreSQL上实现仅用20分钟和12GB内存索引1亿向量,相比同类方案实现百倍性能飞跃。
性能突破:从40小时到20分钟
在PostgreSQL平台上处理1亿(768维)向量索引,VectorChord 完成了以下近乎不可能的优化:
- 构建速度:从约40小时缩短至20分钟。
- 内存消耗:从约200 GB降低至12 GB,节省了超过7倍的内存资源。
这意味着,用户现在可以使用更廉价、配置更低的机器来完成此前需要高端硬件才能支撑的任务:
| 实例 |
价格 |
内存使用/总内存 |
备注 |
| 优化前最低要求 (i7i.8xlarge) |
🟨 每月 2174 美元 |
135 GB / 256 GB |
用于更快索引 |
| 优化后推荐 (i7i.4xlarge) |
✅ 每月 1087 美元 |
12 GB / 128 GB |
最低要求 |
| 经济型方案 (i7i.xlarge + GPU) |
✅ 每月 272 美元 + GPU成本 |
6 GB / 32 GB |
需GPU辅助索引 |
这一切得益于针对索引构建三个核心阶段(初始化、插入、压缩)的“三板斧”优化:
| 优化 |
目标阶段 |
优化结果 |
| 分层K-均值 + 降维 |
1️⃣ 初始化 |
30分钟(GPU)→8分钟(CPU),内存135→23 GB |
| 减少锁争用 |
2️⃣ 插入 |
420分钟→9分钟 |
| 并行化压缩 |
3️⃣ 压缩 |
8分钟→1分钟 |
技术深潜:三大核心优化原理
1. 初始化阶段:让聚类快如火箭
初始化阶段的核心瓶颈是K-means聚类,其传统复杂度为 O(NKdI),既耗时又耗内存。
分层K-均值 (Hierarchical K-means)
为了突破线性加速限制,我们将采样向量划分为多个不相交子集并行聚类。通过先执行一次小规模K-means获取质心,再将向量分配至各子集,时间复杂度显著降低。当子集数量 M=64,子集内质心数 K‘=25 时,理论加速比可达约3200倍。
降维 (Dimensionality Reduction)
为了将采样所需的140GB内存降至可接受范围,我们应用了Johnson-Lindenstrauss变换。该引理保证高维点集可被嵌入到低维空间(如从768维降至100维)而几乎保持距离不变。我们在采样时直接应用此变换,在低维空间进行聚类,再通过二次采样映射回高维质心。此举将内存占用降至23GB,并使聚类速度提升约7倍。
高效采样 (Sampling)
我们摒弃了低效的全表扫描蓄水池采样,转而利用PostgreSQL的表采样接口。通过实现基于Feistel网络的伪随机置换函数,可以惰性生成随机块序列,实现仅访问采样向量的高效块采样。
综合以上三点,初始化阶段总时间被压缩至8分钟。
2. 插入阶段:破解并发瓶颈
插入阶段曾受困于严重的锁争用问题,导致在16 vCPU实例上CPU利用率仅40%,耗时数小时。
减少链表争用
原设计中所有工作进程共享一个全精度向量链表,导致高频插入时争用激烈。我们将其拆分为 M 个链表(M 为工作进程数),让每个进程独立写入自己的链表,消除了这一主要争用点。
减少页面扩展锁争用
火焰图分析显示,大量时间耗费在LockRelationForExtension上,这是PostgreSQL防止索引并发扩展的粗粒度锁。我们升级并应用了PostgreSQL 16+的新API,显著缩小了临界区。
批量页面扩展
尽管锁粒度已细化,页面扩展本身仍是瓶颈。我们通过一次性请求扩展16个页面,触发PostgreSQL底层使用更高效的fallocate系统调用,而非多次pwrite。优化后,写入吞吐量稳定在1.8 GB/s,CPU利用率达90%。
至此,插入阶段耗时降至9分钟。
3. 压缩阶段:并行化收官之战
向量插入后,需从“以插入为导向”的非紧凑布局转换为“以搜索为导向”的紧凑布局(每32个向量一组,优化SIMD)。此阶段原是串行过程,耗时约8分钟。
我们将其并行化:若存在 M 个工作进程和 N 个叶节点,则第 i 个节点的子节点由第 i mod M 个工作进程处理。优化后,压缩阶段仅在1分钟内完成。
实践:构建亿级向量索引
经过VectorChord 1.0.0的优化,现在可以在中等配置的实例上高效构建高性能索引。以下是一个针对LAION-100M数据集的索引创建示例:
CREATE INDEX ON laion USING vchordrq (embedding vector_ip_ops)
WITH (options = $$
build.pin = 2
[build.internal]
lists = [400, 160000]
build_threads = 16
spherical_centroids = true
kmeans_algorithm.hierarchical = {}
kmeans_dimension = 100
sampling_factor = 64
$$);
此配置在i7i.4xlarge实例上,仅用18分钟即完成索引构建,在120 QPS下检索TOP-10的召回率(Recall)达到94.9%。
总结与展望
VectorChord 1.0通过分层聚类与降维、细粒度并发控制、并行压缩等核心技术,彻底改变了在PostgreSQL上进行大规模向量索引构建的范式,使其变得快速、经济且易于实施。这为在传统关系型数据库体系中集成高性能人工智能检索能力提供了强有力的支撑。
除了VectorChord,数据库生态内对向量检索的优化竞赛正在升温。许多厂商正致力于提供同时支持向量、全文、标量及混合搜索的一体化方案,例如海量Vastbase的向量版、OceanBase的SeekDB等,这预示着向量检索能力正成为现代数据库的标配。