【发布时间】:2021-12-01 18:27:24
【问题描述】:
我正在寻找改进 Postgres(分区)表中数据删除的方法,而不是降低访问性能。
使用:Postgres 10.2
忽略一些不相关的列,我的表 transactions 包含这些列(省略了一些不相关的列):
transaction_id PK
location
type
user_id
transaction_date
关于当前表的一些要点:
- 在生产中,它有大约 1 亿行
- 根据
user_id(模100)对表进行分区(手动)。这意味着带有user_id3 的用户的交易将转到transactions_3和user_id2356 将转到transactions_56。 - 我们手动插入记录,因为 Postgres(10) 不支持这种开箱即用的分区,而且我们已经知道必须为其插入事务的用户(在检索时也是如此)
什么效果好:插入和检索,因为我们已经知道用户 - 我们知道要查看哪个表,因此不必遍历 100 个分区来找到它。 p>
什么没有:我们有一个经常删除旧数据的过程 - 基于用户订阅。但这通常会导致问题(空间问题),因为删除的数据不会立即释放。由于大量更新或删除活动导致表包含大量死行版本时,普通的 VACUUM 可能还不够(就像我们这里的情况)
我们希望如何改进这一点是能够根据交易日期将数据存储在分区中 - 然后能够在订阅结束时删除表。这将确保该空间立即再次可用。
简而言之,我们的主要目标是改进删除过程,以便立即恢复空间 - 同时确保访问性能不会恶化
对此我有几个问题:
- 如果我们根据日期对表进行分区,我认为这(至少访问)会变慢,因为它现在必须扫描所有 100 个表以查看事务 ID 的位置?
- 是否真的有可能实现这一点,保持事务检索与以前一样 - 同时改进删除过程。如果有,怎么做?
- 我认为将它在日期和帐户上进行分区并不是一个真正可行的\好的解决方案 - 由于可以创建大量表? (需要保留数据最长 2 年)
- 为此,我们是否需要迁移到更新的 Postgres,比如 Postgres 14(它是最新的)。我知道升级到最新版本总是好的。但我想知道 - 如果不升级 Postgres 是否真的可以做到这一点。
希望在这里得到一些关于前进道路的指导。
【问题讨论】:
-
在您的情况下,为什么 VACUUM 还不够?
-
也许只是停止分区。您已经给出了一些由分区引起的问题,您可以轻松解决这些问题。但是你没有列出任何实际的好处。所以也许只是停止这样做。如果您没有 100 个分区,则无需“遍历 100 个分区”。
-
@jjanes 来自文档:当由于大量更新或删除活动而导致表包含大量死行版本时,普通 VACUUM 可能无法令人满意。我们确实有大量的删除活动。而且我认为在我的情况下需要对更大的数据集进行分区(预计会进一步增长)-并且不分区可能会使记录检索的性能更差?
-
文档中的关键词是“可能”。为什么在 this 的情况下,为 you 提供空间供内部重复使用是不够的?我当然知道为什么它在其他情况下可能不够用。
标签: postgresql partitioning postgresql-10 vacuum table-partitioning