为何 RAG 向量存储应优先考虑 PostgreSQL + pgvector 而非 MySQL?
构建检索增强生成(RAG)系统已成为释放大型语言模型(LLM)潜力的关键范式。通过将 LLM 的推理能力与外部知识库的实时、特定信息相结合,RAG 能够生成更准确、更相关、更值得信赖的回答。而这个“外部知识库”的核心,往往是以向量嵌入(Vector Embeddings)形式存在的海量文本数据。
因此,选择一个既能存储又能高效检索这些高维向量的数据库,成为了 RAG 系统架构设计的重中之重。在关系型数据库领域,MySQL 和 PostgreSQL 无疑是两大巨头。然而,当涉及到 RAG 应用中至关重要的向量相似度搜索任务时,PostgreSQL 配合其 pgvector 扩展,展现出了标准 MySQL 难以企及的优势。
这篇博文将深入剖析技术细节,解释为什么对于严肃的 RAG 应用,pgvector 通常是那个更合适的“扳手”。
理解 RAG 对向量存储的核心诉求
一个典型的 RAG 流程需要数据库满足以下关键能力:
-
存储高维向量: 现代嵌入模型(如来自 OpenAI, Sentence-Transformers 等)产生的向量通常具有数百甚至数千个维度(例如 768, 1024, 1536 维)。数据库需要能原生或高效地存储这些密集浮点数数组。
-
存储关联元数据: 每个向量通常需要与原始数据(如文档块文本、来源 URL、创建时间等)关联。数据库必须能方便地存储这些结构化或半结构化的元数据。
-
执行高效的相似度搜索: 这是 RAG 的性能瓶颈所在。当用户提问(查询向量)时,数据库必须能够极快地(通常是毫秒级)在数百万甚至数十亿的向量中,找到与查询向量“最相似”(语义上最接近)的 Top-K 个向量。这依赖于专门的近似最近邻(Approximate Nearest Neighbor, ANN)搜索算法和索引。
-
结合元数据过滤: 搜索不仅要基于向量相似度,通常还需要结合元数据进行过滤(例如,只在特定部门的文档、特定时间范围内的文档中搜索)。数据库应支持这种混合查询。
-
可扩展性与可靠性: 随着知识库增长,数据库需要能够水平或垂直扩展,并保证数据的持久性和一致性。
现在,让我们看看 PostgreSQL + pgvector 和标准 MySQL 在满足这些需求上的表现差异。
PostgreSQL + pgvector:为向量而生(在关系型框架内)
pgvector 是一个 PostgreSQL 扩展,它巧妙地将向量数据库的核心功能集成到了成熟的 PostgreSQL 生态中。
-
原生 vector 数据类型: pgvector 引入了 vector(DIM) 类型。你可以直接 CREATE TABLE my_docs (id SERIAL PRIMARY KEY, content TEXT, embedding vector(1536));。数据库“理解”这是一个向量,为后续优化奠定了基础。存储紧凑,无需应用层进行复杂的序列化/反序列化转换。
-
强大的 ANN 索引支持: 这是 pgvector 的杀手锏。 它实现了两种业界领先的 ANN 索引算法:
-
IVFFlat (Inverted File with Flat Compression): 基于聚类的思想,将向量空间分割成多个区域(lists)。搜索时,通过 probes 参数指定仅探测查询向量最可能落入的少数几个区域,大大减少了需要比较的向量数量。适合中等规模数据,参数相对直观。
-
HNSW (Hierarchical Navigable Small World): 构建一个多层的、类似导航图的复杂结构。在高层进行快速跳转,在低层进行精细搜索。通常在性能(速度和召回率)上优于 IVFFlat,尤其对于大规模数据集,但索引构建更耗时,内存占用也更大。
这些索引使得在百万级甚至更大规模向量集合上实现亚秒级(通常是几十到几百毫秒)的相似度搜索成为可能。
-
-
内置距离/相似度函数: pgvector 提供了高效的 SQL 操作符来计算向量间的核心距离/相似度:
-
<-> (L2 / Euclidean Distance): 向量空间直线距离。
-
<=> (Cosine Distance): 衡量向量方向的差异,是文本语义相似度最常用的度量。距离越小(0-2范围,越接近0),余弦相似度越高(-1到1范围,越接近1)。
-
<#> (Inner Product): 内积。对于归一化向量,内积越大越相似(注意 pgvector 的 <#> 返回负内积,值越小越相似)。
计算在数据库内部用 C 语言实现,效率远高于应用层或 SQL UDF。
-
-
无缝结合关系型能力: 你可以在同一个 SQL 查询中,轻松地混合向量相似度搜索和标准的 WHERE 子句过滤元数据。例如:
SELECT id, content FROM my_docs WHERE category = 'finance' AND updated_at > '2023-01-01' ORDER BY embedding <=> query_vector -- query_vector 是你的查询向量 LIMIT 10;
content_copydownload
Use code with caution.SQL这种整合能力极大地简化了 RAG 应用的逻辑。
-
成熟的 PostgreSQL 生态: 继承了 PostgreSQL 的事务、备份恢复、权限管理、丰富的数据类型、强大的 SQL 标准支持、大量的客户端工具和 ORM 支持等所有优点。
标准 MySQL:向量处理的“先天不足”
标准的 MySQL(社区版或企业版,不包括特定云服务如 HeatWave)在处理向量数据,尤其是高效搜索方面,存在明显的短板:
-
缺乏原生向量类型: 你必须“曲线救国”,将向量存储为:
-
BLOB / LONGBLOB: 需要应用层进行序列化(例如转为 bytes)和反序列化。数据库对此内容一无所知。
-
TEXT / LONGTEXT: 存储为 JSON 字符串或逗号分隔值。同样需要应用层解析,且文本存储效率通常低于二进制。
-
多个 FLOAT 列:仅适用于极低维度,对 RAG 完全不现实。
这种模拟方式不仅不便,还可能带来性能开销和存储空间的浪费。
-
-
致命缺陷:无内置 ANN 索引: MySQL 的标准索引(B-Tree, Hash, Full-Text, Spatial (R-Tree))根本不适用于高维向量空间的近邻搜索。
-
B-Tree/Hash: 设计用于精确匹配或范围查询,对高维空间距离无效。
-
Full-Text: 用于关键词搜索,与向量语义相似度无关。
-
Spatial (R-Tree): 主要用于低维地理空间数据(2D/3D),在高维空间下性能会急剧下降(维度灾难 Curse of Dimensionality)。
这意味着,在标准 MySQL 中进行向量相似度搜索,唯一的选择是进行全表扫描! 数据库必须读取表中的每一条记录,将 BLOB 或 TEXT 反序列化成向量,然后与查询向量计算距离,最后排序。对于哪怕只有几万个向量的数据集,这也会导致搜索时间达到秒级甚至分钟级,完全无法满足 RAG 系统的实时性要求。这是标准 MySQL 不适合做大规模向量数据库的根本原因。
-
-
距离计算困难: MySQL 没有内置函数直接计算向量的余弦相似度或欧氏距离。你必须:
-
将所有向量拉到应用层计算:产生巨大的网络 I/O 和应用服务器 CPU 负担。
-
尝试编写用户定义函数 (UDF):可能性能不佳,且增加了部署和维护的复杂性。
-
-
混合查询效率低: 虽然可以存储元数据,但由于无法高效地先通过向量相似度缩小范围,混合查询(例如 WHERE metadata_col = 'X' ORDER BY vector_distance LIMIT K)的效率也会受限于缓慢的向量扫描。
那 MySQL HeatWave Vector Store 呢?
值得一提的是 Oracle Cloud Infrastructure (OCI) 上的 MySQL HeatWave 服务包含了 Vector Store 功能。它确实为 MySQL 增加了内置的、由 HeatWave 分析引擎加速的向量存储和 ANN 搜索能力。如果你的基础设施在 OCI 上,并且已经在使用或计划使用 HeatWave,那么它是一个值得考虑的选项。但这并非标准的、通用的 MySQL 功能,它绑定于特定的云服务和架构。
结论:选择比努力更重要(在选型阶段)
对于构建 RAG 应用而言,向量存储和检索的性能是决定系统成败的关键因素之一。
-
标准 MySQL 在这方面存在结构性短板,缺乏必要的原生向量支持和(最重要的)ANN 索引机制,导致无法进行高效的相似度搜索。用它来存储 RAG 向量,无异于用马车去参加 F1 比赛。
-
PostgreSQL + pgvector 则提供了一个强大、集成且高效的解决方案。它将高性能的向量搜索能力无缝融入到了成熟、可靠的关系型数据库中,让你可以在熟悉的 SQL 环境下,同时利用关系型数据的严谨性和向量数据的语义能力。加之活跃的社区和良好的工具链(如 LangChain, LlamaIndex, Spring AI 等)支持,使得开发和部署 RAG 应用更为顺畅。
当然,对于超大规模(如数十亿级向量)或对延迟、吞吐量有极致要求的场景,专门的向量数据库(Milvus, Pinecone, Weaviate, Qdrant 等)可能是更优选择。但对于绝大多数需要在关系型数据库基础上扩展 RAG 能力的应用来说,PostgreSQL + pgvector 提供了一个性能优异、功能全面、易于集成且成本效益高的绝佳方案,明显优于使用标准 MySQL 的尝试。
对比:PostgreSQL + pgvector vs. 标准 MySQL
特性 | PostgreSQL + pgvector | 标准 MySQL (社区版/企业版) | 对 RAG 的影响 |
向量数据类型 | ✅ 原生 vector 类型 | ❌ 无原生类型 (需用 BLOB, TEXT 或 JSON 模拟) | 易用性 & 效率: pgvector 更直观,存储可能更紧凑,避免序列化/反序列化开销。 |
向量索引 | ✅ 专用 ANN 索引 (IVFFlat, HNSW) | ❌ 无内置 ANN 索引 (标准索引如 B-Tree 不适用) | 性能: 这是决定性因素! pgvector 可实现毫秒级 ANN 搜索;MySQL 只能全表扫描,极慢。 |
距离/相似度计算 | ✅ 内置 SQL 操作符 (<=>, <->, `<#>) | ❌ 无内置函数 (需应用层计算或低效 UDF) | 效率 & 简洁性: pgvector 直接在数据库层高效计算;MySQL 方案要么慢,要么复杂。 |
数据整合 | ✅ 结构化数据 + 向量数据 同库管理 | ✅ (同理,但向量处理能力弱) | 架构简洁性: 两者都可,但 pgvector 能在一个库内高效处理两种数据,简化架构。 |
生态系统 | ✅ pgvector 社区活跃,集成工具多 (LangChain, Spring AI等) | ✅ MySQL 生态成熟 (但缺乏向量工具集成) | 开发效率: pgvector 在 AI/RAG 领域有更好的工具链支持。 |