【问题标题】:How to automatically remove old tuples from a database?如何从数据库中自动删除旧元组?
【发布时间】:2020-11-18 20:32:04
【问题描述】:

我正在开发一个网关应用程序,并且我正在使用 PostgreSQL 来存储接收到的数据,然后再转发它们。 为了避免磁盘饱和,我想删除所有超过某个时间的元组(此时我正在考虑 30 或 60 天)。

为了实现这一点,目前,我编写了一个触发器,在某个表中的每个 INSERT 语句之后,删除所有早于这个特定时间量的条目(您可以在下面找到它)。它似乎有效,但我有点害怕约会率更高会发生什么。

DROP TRIGGER IF EXISTS delete_old_measures
ON my_table_1;
CREATE OR REPLACE FUNCTION dropOldMeasures() RETURNS TRIGGER AS $$
    BEGIN
        DELETE FROM my_table_1 WHERE sqltime < now()-'30 day'::interval;
        RETURN NULL;
    END;
    $$
    LANGUAGE 'plpgsql';

CREATE TRIGGER delete_old_measures
AFTER INSERT
ON my_table_1
FOR EACH ROW EXECUTE PROCEDURE dropOldMeasures();

我的问题是:有没有更聪明的方法可以自动从数据库中删除旧元组?

【问题讨论】:

    标签: sql postgresql automation triggers sql-delete


    【解决方案1】:

    DELETE 不是删除大量记录的好方法,因为它会产生大量开销。

    对于大型表,经常使用使用table partitioning 的方法。基本上,表分区意味着单个表基于分区键存储在多个不同的文件中。在您的情况下,分区键将基于sqltime - 根据您的需要,它可能是一小时或一天或一周或一个月或其他任何时间。

    这样的想法是您可以非常轻松地按计划删除分区。与删除相比,删除分区对数据库的消耗要小得多。

    【讨论】:

      【解决方案2】:

      即使您确实想使用触发器来执行此操作,也肯定没有理由为每一行执行此操作。每个语句一次就足够了。

      如果您不知道我在说什么,请查看PosgreSQL documentation for triggers,或者更好的是,查看解释how to create a trigger 的页面。

      最好学习如何使用调度程序(如 Linux 上的cron 或 Windows 上的Task Scheduler)来定期安排此操作。

      DELETE 释放的空间不能供 INSERT 重复使用,直到运行 Vacuum。因此,除非您要在表上运行“手动”VACUUM(或改用分区),否则批量删除小于 autovacuum_vacuum_scale_factor(默认为 0.2)可能没有多大意义。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-24
        • 2019-03-18
        • 2011-02-09
        • 1970-01-01
        • 2020-05-30
        • 2020-05-31
        相关资源
        最近更新 更多