Alexander Ioffe:Postgres 19 图查询有多快?第一部分:它们实际在做什么?

Alexander Ioffe:Postgres 19 图查询有多快?第一部分:它们实际在做什么?

💡 原文英文,约10500词,阅读约需38分钟。
📝

内容提要

Postgres 19的SQL/PGQ图查询在固定深度时与手写JOIN性能相同,因其本质是重写为JOIN。但可变深度查询(如爆炸半径)不受支持,需用递归CTE,性能随可达节点数线性增长。Apache AGE支持Cypher可变长度遍历,但比递归CTE慢约2倍。所有实现均基于索引遍历,非原生图引擎的索引无关邻接。

🔎

延伸解读

固定深度:图查询就是JOIN

Postgres 19的SQL/PGQ在固定深度查询时,与手写JOIN生成完全相同的执行计划,性能几乎一致。这是因为SQL/PGQ本质是一个重写器,将图模式转换为关系JOIN。因此,对于固定深度的遍历,图查询带来的主要是可读性提升,而非性能优势。

可变深度:PG19的短板

Postgres 19beta1不支持可变深度图查询,无论是无界还是有限量词都会报错。这意味着“爆炸半径”这类查询仍需使用递归CTE。虽然未来版本可能支持量词,但预计性能与递归CTE相当,因为底层仍是索引遍历,而非原生图引擎的索引无关邻接。

Apache AGE:功能补全但性能打折

Apache AGE提供了PG19缺失的Cypher可变长度遍历语法,但性能约为递归CTE的2倍。这是因为AGE在索引遍历之上增加了函数扫描层。对于需要可变深度查询的用户,AGE是一个可选方案,但需权衡性能开销。

Q&A

Postgres 19 的 SQL/PGQ 图查询在固定深度时性能如何?

在固定深度(如4跳)查询时,Postgres 19 的 SQL/PGQ 图查询与手写 JOIN 性能相同,因为 SQL/PGQ 本质上是将图模式重写为 JOIN。实测中,两者执行时间都在亚毫秒级,且随着数据量增长保持平稳。

Postgres 19 支持可变深度图查询吗?

Postgres 19 的 SQL/PGQ 不支持可变深度查询,包括有界和无界的量词(如 -[e]->{1,} 或 {1,10})都会报错。目前只能使用递归 CTE 来实现类似功能。

Postgres 19 的图查询与 Apache AGE 在可变深度遍历上性能有何差异?

Apache AGE 支持 Cypher 的可变长度遍历,但性能比递归 CTE 慢约2倍,因为它是在索引遍历之上增加了函数扫描层。而 Postgres 19 本身不支持可变深度,需用递归 CTE。

Postgres 19 的图查询实现原理是什么?

Postgres 19 的 SQL/PGQ 是一个重写器,它将图模式重写为关系型 JOIN 树,然后由优化器处理。它不是原生图存储引擎,没有索引无关的邻接,而是基于索引遍历。

Postgres 19 的图查询在规划时间上有什么特点?

图查询的规划时间比手写 JOIN 稍长,例如在 10,000 个负载均衡器时,图查询规划时间约 7.145 ms,而手写 JOIN 约 2.965 ms。但执行时间几乎相同。

Postgres 19 的图查询适合哪些场景?

适合固定深度的图遍历,例如查找指定节点下游固定跳数的节点。它提供了更清晰的语法,但性能与手写 JOIN 相同。对于可变深度查询,目前需使用递归 CTE。

🏷️

标签

➡️

继续阅读