【问题标题】:How do I limit number of records in table, so that old records are deleted, but new rows are kept?如何限制表中的记录数,以便删除旧记录,但保留新行?
【发布时间】:2019-07-10 18:23:20
【问题描述】:

我在我们的 oracle 数据库中有一个表,它根据 Web 应用程序中的用户会话跟踪下载。在过去的几年里,这张表已经增长到数百万条记录,这正在拖慢应用程序的速度。

我想将此表限制为仅保留过去一周的项目,并让它自动删除较旧的记录。该表有一个名为 DOWNLOAD_DATE 的日期字段,可用于此查询。

这是我可以用触发器做的事情吗?如果是这样,最好的方法是什么?

【问题讨论】:

  • 你可以通过索引或表分区来解决性能问题。
  • 确实如此,但分区仅在企业版中可用且仅作为付费选项提供。
  • 好吧,您显然是在商业环境中使用它。我建议您为所需的功能付费。答案是“分区”。
  • 看看dbms_scheduler。每天/每小时/每天运行一项作业以删除行/删除分区。

标签: sql oracle plsql database-trigger


【解决方案1】:

我不认为触发器是正确的,因为它在每次插入/更新/删除时执行。我建议为执行类似“从表名中删除 trunc(download_date)

然后您根据需要安排该程序每小时或每天执行一次。

删除后,您可能希望使用“DBMS_STATS.GATHER_TABLE_STATS ('schema_name', 'table_name');”刷新表统计信息

更多关于收集统计数据的信息可以在这里找到:http://www.dba-oracle.com/t_dbms_stats_gather_table_stats.htm

【讨论】:

    【解决方案2】:

    这是我可以用触发器做的事情吗?如果是这样,最好的方法是什么 这样做?

    我想说,Statement level 触发器非常适合这个问题。了解语句级触发器Here

    查看演示:

    SQL> CREATE TABLE tab2 (
        col          VARCHAR(1),
        start_date   DATE,
        end_date     DATE
       );
      /
     Table created
    
    SQL> Select * from tab2;
    COL START_DATE  END_DATE
    --- ----------- -----------
    A   11-07-2019  18-07-2019
    A   11-07-2019  31-07-2019
    A   06-07-2019  31-07-2019
    A   01-07-2019  31-07-2019  --- See this row is 10 days older than Sysdate
    
    -- Created Statement level trigger 
    SQL> CREATE OR REPLACE TRIGGER t1
      2  BEFORE  INSERT ON tab2
      3  BEGIN
      4      DELETE FROM tab2
      5      WHERE start_date <= SYSDATE - 7; -- Deleting records older that 7 days from sysdate
      6  END;
      7  /
    Trigger created
    
    SQL> Insert into tab2 values('A',sysdate+1,sysdate+10);
    1 row inserted
    
    SQL> commit;
    Commit complete
    
    -- You can see the records older that 7 days from sysdate is deleted
    SQL> Select * from tab2;
    COL START_DATE  END_DATE
    --- ----------- -----------
    A   11-07-2019  18-07-2019
    A   11-07-2019  31-07-2019
    A   06-07-2019  31-07-2019
    A   12-07-2019  21-07-2019
    

    【讨论】:

      【解决方案3】:

      如果我有这样的要求,我会这样:

      程序 p1 是 开始 环形 DELETE FROM table123 --- 你可以在这里给你的表名 WHERE download_date

        EXIT WHEN SQL%ROWCOUNT = 0;
      
        COMMIT;
      
        DBMS_LOCK.sleep (10); ----- if you want to give sleep time as per your requirement
      

      结束循环; 结束;

      此作业将运行 24*7 并删除所有超过 7 天的记录

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多