【问题标题】:PostgreSQL table design for frequent "save" action in web appPostgreSQL 表设计用于 Web 应用程序中的频繁“保存”操作
【发布时间】:2018-09-27 01:58:03
【问题描述】:

我们拥有 100,000 个并发用户的基于网络的应用有一个用例,我们每 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");

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

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

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

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

感谢任何指点,谢谢!

【问题讨论】:

  • 是否有机会将modify_date 字段也移动到 JSON 列中?
  • 我们肯定需要该索引,因为它用于应用程序的各个部分进行排序。如果 modify_date 字段是从 inside jsonb 列索引的,会有所不同吗?我对此表示怀疑。
  • 嗯,是的,如果您完全删除 modify_date 并将该信息保留在 JSON 中,它会,因为这样仍然可以进行 HOT 更新。但是,听起来这对你来说不是一个选择。
  • 感谢@TimBiegeleisen,挑战是我们需要索引。无论是列本身还是 JSON 内部,索引都将位于列上或 JSON 内的值上。但是索引是必须的。除非我们改变表格设计,只做INSERTs,是吗?

标签: postgresql performance optimization


【解决方案1】:

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

您有多种选择:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    相关资源
    最近更新 更多