Postgres 不慢,是你的存储太慢

Postgres isn't slow, your storage is

Postgres 不慢,是你的存储太慢

在 POSETTE 2026 大会上,Sai Srirampur 通过实测揭示了一个被忽视的真相:Postgres 性能瓶颈往往不在数据库本身,而在存储层。当数据量增长,慢速存储会导致写入变慢、读取延迟不可预测、autovacuum 滞后以及 checkpoints 争抢资源。基准测试显示,在相同硬件下,本地 NVMe 相比 gp3 EBS 能让吞吐量提升 9 倍,延迟从 36 毫秒降至 4 毫秒。文章进一步提出,通过基于多数派的同步复制结合外部备份,完全可以在生产环境中安全使用本地 NVMe,既享受极致性能,又保障数据高可用。

慢速存储导致的问题并非总是显而易见,但往往是多个看似无关的 PostgreSQL 性能问题的根本原因。
  1. mmnfrdmcx

    云存储贵得离谱,效率还低。太多工程师不懂网络存储的 I/O 往返有多慢,或者虚拟机里那些爱“闲聊”的邻居跟裸机比起来有多拉胯……

  2. bob1029

    SQLite 加 NVMe 有时候感觉像是在作弊。如果我的首要需求是尽可能低的延迟,我实在想不出会选别的方案。

    根据我的经验,Kestrel (AspNetCore) + SQLite + NVMe 全在同一台机器上运行时,性能简直炸裂。想象一下,处理整个表单提交并修改数据库状态,耗时仅需几十到几百微秒。服务任何 HTTP 请求的总墙钟时间完全可以控制在 1 毫秒以内。如果你的 CPU 平均处理时间是 30 微秒,那么在 16-32 核的机器上,你每秒能处理近五十万次请求。

  3. smartbit

    CloudNativePG 将 Kubernetes Local Storage 作为其主要功能之一支持 [0]

    持久卷管理,包括:

    支持带有 PVC 模板的本地持久卷。

    在 Pod 中复用持久卷存储。

    为 WAL 文件和表空间分配独立的卷。

    章节《临时 PostgreSQL 集群降级》[1] 描述了如何设置,并以以下内容开头:

    > 虽然标准方法能确保服务可靠性并利用 Kubernetes 的自愈能力,但在某些场景下,运行一个暂时降级的集群也是可以接受的。这对于依赖节点本地存储的 PostgreSQL 集群尤其相关,这里的存储是本地于运行 PostgreSQL 数据库的 Kubernetes 工作节点的。节点本地存储(或简称本地存储)被用来提升性能。

  4. CharlieDigital

    “想当年”,我们不得不仔细规划底层存储阵列,才能从数据库服务器中榨出每一滴性能。

    我觉得有一代开发者把大内存池和 SSD 视为理所当然;他们脑子里缺乏“数据库映射底层存储”这一概念的联系。

    一旦我在讨论中点破这一点,他们几乎立刻就能恍然大悟(讨论分区和分片时发生过这种情况),但他们自己从来没能把“查询”映射到“存储在磁盘上的某些数据块”这一事实联系起来。

  5. iancarroll

    最近我们把 RDS 实例从 r8g 迁移到了 r8gd,后者增加了本地 NVMe。我觉得平均 I/O 延迟从 1.0ms 降到了 0.1ms。在大查询里,这差距可是会累积起来的!

  6. dangoodmanUT

    这是网络存储的根本问题:上层所有应用都假设小 I/O 既快又本地,因此网络延迟无法被分摊。

    有了应用层复制,你可以将其分摊到几个步骤(例如,提交时进行 2PC)。

    当然这里有细微差别,特别是如果你必须从另一个节点读取数据,但这正是为什么将复制尽可能向上层移动通常在数据库上表现更好——数据库比磁盘更清楚何时该触碰网络。

  7. nasretdinov

    老实说,网络附加存储(NAS)只有在用 HDD 的时候才讲得通。为了所谓的“操作灵活性”而在 IOPS 和延迟上付出 10 倍的代价,简直荒谬。如果你坚持使用本地 NVMe 加复制,架构会简单得多,也健壮得多——而且你本来就不能在(同样带复制的)网络块存储方案中省略这一步……

  8. kebsup

    我用 Postgres 用了很久很久,才搞清楚“索引扫描”和“仅索引扫描”的区别。

    在索引中包含相关列可以极大提升性能,因为 Postgres 不需要再去读取原始表中那些随机排序的元组了。

同日更多故事

2026-10-12