【发布时间】:2022-02-13 12:58:38
【问题描述】:
Postgres 版本:PostgreSQL 10.9 (Ubuntu 10.9-1.pgdg16.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609, 64-bit
在我提出问题之前,我想解释一下我为什么要研究这个问题。我们有一个历史记录表,其中包含超过 500 万行并且每小时都在增长。
随着表长度的增长,选择查询变得越来越慢,即使我们有一个合适的索引。所以我们最理想的选择是删除未使用的旧记录。
方法#1
我们尝试使用简单的delete from table_name where created_date > certain_date where is_active = false从表中删除记录
- 这花了很长时间。
方法 #2
创建一个脚本,该脚本将使用基于光标的方法删除行。
- 这也需要很长时间。
方法#3
-
创建了一个新的未记录表。
-
在 new_table 上创建索引。
-
将旧表中的内容复制到新表中
-
然后记录设置表。
-
将主表重命名为备份。
-
这种方法存在问题,需要一些停机时间。
在实时制作实例上,这会导致数据丢失/导致失败
方法#4
在进一步调查中,删除未使用行的高效方法是,如果我们创建一个分区为 https://www.postgresql.org/docs/10/ddl-partitioning.html 的表 - 我们可以立即删除整个分区。
上述方法的问题是
- 如何在现有表上创建分区?
- 这需要停机吗?
- 如何配置 Postgres 自动创建分区,我们真的不能每天手动创建分区吗?
也欢迎任何其他方法,问题是我真的希望这是自动化而不是手动,因为我会将其扩展到多个表。
请告诉我你的想法,这将非常有帮助
【问题讨论】:
-
@a_horse_with_no_name 我们正在使用
PostgreSQL 10.9 (Ubuntu 10.9-1.pgdg16.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609, 64-bit -
@a_horse_with_no_name 抱歉将链接更改为 10 链接。但是问题还是一样的。
-
如果按日期进行分区,您必须定义适合您的用例的时间粒度级别,无论是一年、季度还是一个月。您的分区功能/索引会将您的数据推送到正确的分区中。然后,您可以通过脚本或手动将最旧的分区切换为新分区。我会说 500 万条记录并不是一个巨大的数字。也许您缺少正在使用的查询之一的覆盖索引。
标签: sql postgresql automation