0

我正在寻找改进 Postgres(分区)表中数据删除的方法,而不是降低访问性能。

使用:Postgres 10.2

忽略一些不相关的列,我有transactions这些列的表(省略一些不相关的列):

transaction_id PK
location
type
user_id
transaction_date

关于当前表的一些要点:

  1. 在生产中,它有大约 1 亿行
  2. 该表基于user_id(模 100)进行分区(手动)。这意味着user_id 3的用户的交易将转到2356transactions_3的用户。user_id transactions_56
  3. 我们手动插入记录,因为 Postgres(10) 不支持这种开箱即用的分区,而且我们已经知道必须为其插入事务的用户(也在检索时)

运作良好:插入和检索,因为我们已经知道用户 - 我们知道要查看哪个表,因此不必通过 100 个分区来找到它。

什么不能:我们有一个经常删除旧数据的过程 - 基于用户订阅。但这通常会导致问题(空间问题),因为删除的数据不会立即释放。由于大量更新或删除活动导致表包含大量死行版本时,普通的 VACUUM 可能还不够(就像我们这里的情况)

我们希望如何改进这一点是能够根据事务日期将数据存储在分区中 - 然后能够在订阅结束时删除表。这将确保该空间立即再次可用。

简而言之,我们的主要目标是改进删除过程,以便立即恢复空间 - 同时确保访问性能不会恶化

我对此有几个问题:

  1. 如果我们根据日期对表进行分区,我认为这(至少访问)会变慢,因为它现在必须扫描所有 100 个表以查看事务 ID 在哪里?
  2. 是否真的有可能实现这一点,像以前一样保持事务的检索 - 同时改进删除过程。如果是这样,怎么做?
  3. 我认为在日子和帐户上都对其进行分区并不是一个真正可能的\好的解决方案 - 由于可以创建大量表?(需要保存数据最长2年)
  4. 为此,我们是否需要迁移到更新的 Postgres,比如 Postgres 14(它是最新的)。我知道升级到最新版本总是好的。但我想知道 - 如果没有 Postgres 升级真的可以做到这一点。

希望在前进的道路上得到一些指导。

4

1 回答 1

1

第一:升级 PostgreSQL 将是一个非常好的主意,不仅因为哈希分区是在 v10 之后引入的,而且还因为自 v10 以来分区的性能和特性有很多改进。

我觉得您现在使用的分区方案(自制哈希分区)对您没有多大帮助。您无法通过简单的方式摆脱客户DROP TABLE(这很好),并且在分区中删除 1000 万行并不比在单个大表中删除它们更有趣。相反,一旦 autovacuum 完成,相对膨胀会更多。唯一的优点是 autovacuum 会更有效地工作,因为它可以单独处理每个分区。

要回答您的问题:

  1. 是的,分区使大多数查询变慢;希望不会慢很多。这就是你要付出的代价。

  2. 不,您的查询会变慢一些(与分区数成正比,因此请保持适度)。

  3. 您可以根据这两个条件进行分区,因为分区也可以是分区表。但我质疑这是否真的是一个好主意,因为我怀疑您当前的分区方案是否真的有益。

  4. 是的,至少使用 v12,最好是 v14。

于 2021-10-13T09:40:03.000 回答