首页 > 解决方案 > PostgreSQL 表设计用于 Web 应用程序中的频繁“保存”操作

问题描述

我们拥有 100,000 个并发用户的基于 Web 的应用程序有一个用例,我们每 5 秒自动保存一次用户的活动。考虑这样的表:

create table essays
(
  id                 uuid not null constraint essays_pkey primary key,
  userId             text not null,
  essayparts         jsonb   default '{ }' :: jsonb,
  create_date        timestamp with time zone default now() not null,
  modify_date        timestamp with time zone default now() not null
);

create index essays_create_idx on essays ("create_date");
create index essays_modify_idx on essays ("modify_date");

这对我们来说很有效,因为所有与用户文章相关的东西,例如标题、简短的署名。请求者、全文正文等都essayparts以 JSON 格式存储在列中。为了自动保存文章,我们不会一直插入新行。我们更新每个 ID(每篇文章)及其所有组件。

因此,每篇文章都有很多更新,因为这是一项耗时且深思熟虑的活动。鉴于每 5 秒自动保存一次,如果用户要写半小时,我们会更新她的文章大约 360 次。

使用 PostgreSQL 的“HOT”(仅堆元组)功能就可以了。我们使用的是 v10,所以我们很好。然而,挑战在于我们modify_date每次保存文章时都会更新该列,并且这也有一个索引。这意味着根据 HOT 的原理,这不会从 HOT 更新中受益,并且会发生大量碎片。

我想在网络或移动世界中,这不是一个不寻常的模式。许多服务似乎会自动保存内容。他们只是插入吗?如果是这样,如果用户注销并重新登录,他们如何通过查看max(modify_date)?或者是否有任何其他机制可以利用 HOT 更新同时更新表中的索引列?

感谢任何指点,谢谢!

标签: postgresqlperformanceoptimization

解决方案


对 100000 个并发用户每 5 秒执行一次更新将每秒产生 20000 次更新。这本身就非常具有挑战性,您需要一个好的系统来完成它,但如果这些更新不热,autovacuum 将永远无法跟上。

你有几个选择:

  1. 选择 PostgreSQL 以外的关系数据库管理系统来更新行。

  2. 不要索引modify_date并希望 HOT 能解决问题。

  3. 执行这些更新的频率低于每 5 秒一次(谁需要每 5 秒自动保存一次?)。

  4. 将数据自动保存在数据库以外的其他地方。


推荐阅读