打开网易新闻 查看精彩图片

一、昂贵的图数据库痛点:只跑4条查询,成本却居高不下

很多技术团队都遇到过这样的困境:花重金搭建Neo4j集群,业务上真正用到的查询语句只有4条,全部都是查询人与人之间关联关系。这套集群每个月的开销很高,但仅仅支撑少量的关联遍历逻辑,资源严重浪费。

当PostgreSQL 19 Beta2版本发布,内置SQL/PGQ属性图查询标准之后,这名工程师做了一次大胆的实测。他把生产环境数据拷贝到测试服务器,直接用Postgres接管原本Neo4j承载的关系遍历任务。原本他预想,测试结果一定会证明专用图数据库依旧不可替代,但是实测数据完全推翻了他的预判。

PostgreSQL是开源免费的关系型数据库,官方镜像仓库在GitHub拥有22.2k星标。SQL/PGQ是SQL:2023标准里的属性图查询规范,由Peter Eisentraut在3月份提交代码合并进内核。它不需要新增独立的图存储引擎,也不用额外复制一份数据,仅仅是在现有业务表之上增加一层图元数据定义,逻辑上和视图十分接近。不需要迁移原有业务数据,原有索引、MVCC多版本、行级权限、备份机制全部保留,这也是这项新特性最大的亮点。

这个特性直击开发者痛点:不想维护两套数据库,不想为少量图查询承担图数据库高额运维成本;同时满足大家的痒点,只用一套Postgres,就能写出类似Cypher风格的图匹配语句;最终带来爽点:部分场景下性能超越Neo4j,省去额外图数据库的部署、运维开支。

二、核心原理与实操代码:不用迁移数据,直接定义图结构图模型定义

开发者只需要执行一段DDL语句,基于现有的用户表、关注关系表,声明顶点表和边表,完成属性图的创建。

CREATE PROPERTY GRAPH socialVERTEX TABLES (users KEY (id) LABEL person PROPERTIES (id, name)EDGE TABLES (follows KEY (id)SOURCE KEY (src) REFERENCES users (id)DESTINATION KEY (dst) REFERENCES users (id)LABEL knows
图查询语句

定义完成之后,可以使用GRAPH_TABLE语法,编写和Cypher风格高度相似的关联匹配查询。

SELECT * FROM GRAPH_TABLE (socialMATCH (a IS person WHERE a.id = 42)-[IS knows]->(b IS person)COLUMNS (b.id, b.name)
底层转换逻辑

GRAPH_TABLE本质是查询重写器。我们写好的箭头匹配语法,会在进入优化器之前,自动转换成普通多表JOIN。

  • 开发者编写:MATCH (a)-[k]->(b)
  • 数据库实际执行:users表a关联follows边表k,再关联users表b 单跳关系会转为三表连接,两跳转为五表连接,三跳转为七表连接。查询优化器会自动选择连接顺序,复用Postgres原有的统计信息、索引能力和执行计划。
实测环境与性能数据

测试机器配置:16核CPU,64G内存,本地NVMe固态。数据为脱敏生产数据,包含410万用户,3800万条关注边记录。 Postgres19 Beta2参数:shared_buffers 16GB,work_mem 128MB,effective_cache_size 48GB。 Neo4j 5参数:堆内存16GB,pagecache 24GB。 两个数据库都预热完成,每组查询取500次运行的中位数,客户端和数据库部署在同一台主机,排除网络干扰。

查询场景

Neo4j耗时

Postgres19耗时

优胜方

根据ID单跳关联

1.8毫秒

1.1毫秒

Postgres

两跳关联去重

14毫秒

9毫秒

Postgres

两跳关联过滤计数

22毫秒

12毫秒

Postgres

三跳关联去重

61毫秒

148毫秒

Neo4j

两跳场景下Postgres执行计划全部命中索引,没有磁盘读取,性能表现十分亮眼。

三、辩证思考:优势很明显,但存在无法忽视的短板

从好的一面来看,SQL/PGQ的优势足够吸引人。团队不需要额外学习一套全新数据库,原有DBA、运维体系可以直接复用。不用同步维护两套数据,避免数据同步带来的一致性问题。简单的一跳、两跳关联查询,Postgres性能反而超过Neo4j,对于大量轻量图查询场景,完全可以替换掉昂贵的图数据库。

但这次测试也暴露了很关键的问题,工程师踩过一个典型的索引陷阱。在做反向遍历查询的时候,第一次执行耗时达到340毫秒,排查执行计划发现,数据库对3800万条边做全表扫描。原因很简单:Neo4j原生支持双向遍历,不需要额外建立反向索引,长期掩盖了表结构设计缺陷。给follows表dst字段新建索引之后,同样的查询耗时直接降到6毫秒。也就是说,使用Postgres做图查询,开发者必须自己考虑双向遍历对应的索引,不会像专用图数据库那样自动兜底。

更大的局限在于,PostgreSQL 19的SQL/PGQ还不支持可变长度路径匹配,没有最短路径能力,也不支持多模式MATCH。如果需要写1到4层可变深度的关联查询,GRAPH_TABLE语法无法实现。只能退回到传统递归CTE写法。

WITH RECURSIVE walk AS (SELECT dst AS id, 1 AS d FROM follows WHERE src = 42UNIONSELECT f.dst, w.d + 1FROM walk w JOIN follows f ON f.src = w.idWHERE w.d < 4SELECT DISTINCT u.nameFROM walk w JOIN users u ON u.id = w.id;

递归CTE最终耗时96毫秒,和Neo4j差距不大,但代码可读性很差,这也是图数据库诞生的核心原因。

综合来看,它不是图数据库的终结者。浅层次固定深度的关系查询,Postgres19可以胜任,降低架构成本;一旦涉及多层可变深度路径、复杂图算法场景,专用图数据库依旧有不可替代的优势。

四、现实意义:技术选型的思路变化

过去,只要业务存在少量关系遍历需求,很多团队第一反应就是引入Neo4j,单独搭建一套图数据库集群,增加架构复杂度、运维工作量和资金成本。PostgreSQL19带来的SQL/PGQ,给技术团队提供了全新选型方案。

对于大多数业务,关联查询深度固定、层数不多,完全可以继续沿用现有的Postgres,不用新增数据库组件。系统架构更简单,数据一致性更容易保障,运维成本大幅下降。

但技术人员不能盲目乐观直接替换。迁移之前,必须梳理清楚图查询的深度、访问模式,评估索引设计成本。如果业务大量使用不定长路径、复杂图挖掘算法,贸然替换,会带来严重性能隐患。

这项特性最大价值,不是消灭图数据库,而是补齐关系型数据库在关联遍历场景的短板,让技术选型不再非黑即白。团队可以根据业务复杂度,灵活选择架构方案,而不是一刀切引入新数据库。

五、互动话题

1、你的项目里有没有引入Neo4j这类图数据库?实际业务中,真正高频使用的图查询多吗? 2、如果项目只是固定1-2层的关联查询,你会考虑用PostgreSQL19的SQL/PGQ,替代掉独立图数据库吗? 3、你觉得未来几年,图数据库市场会不会因为Postgres内置图查询,受到明显冲击?欢迎在评论区交流你的看法。