【问题标题】:Deleting old records from a mysql table but keeping a backup从 mysql 表中删除旧记录但保留备份
【发布时间】:2013-06-07 23:01:17
【问题描述】:

我有一个 MYSQL 表,它只需要今天日期前 30 天的数据。它的数据可能在今天之后的几年内。为了更快地查询,我通常删除旧记录,因为我认为没有必要搜索旧记录。但是,如果我们需要它进行分析,我仍然会保留记录的备份副本。原表是这样的:

CREATE TABLE featured_deal (
     id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      fsa VARCHAR(10),
      poster_id int(11),
      dealid bigint(20),
      bookedDate date,
      createDate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY `featured_unique`(fsa, bookedDate)
    )

我创建了一个表,它是这个表的副本,称为历史:

CREATE TABLE featured_deal_history (
             id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
              fsa VARCHAR(10),
              poster_id int(11),
              dealid bigint(20),
              bookedDate date,
              createDate timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
            UNIQUE KEY `featured_unique`(fsa, bookedDate)
            )

每当原始表上发生插入时,我都有一个触发器来填充历史表:

CREATE TRIGGER `featured_to_history`
            AFTER INSERT ON lst_enmasse_featured_deal 
            FOR EACH ROW
            INSERT INTO lst_enmasse_featured_deal_history (fsa,poster_id,dealid,bookedDate,createDate)
            VALUES (NEW.fsa,NEW.poster_id,NEW.dealid,NEW.bookedDate,NEW.createDate)

最后,我使用 cron 作业和命令清理表:

    DELETE * FROM featured_deal WHERE bookedDate < DATE_SUB(CURDATE(), INTERVAL 30 DAY)

有没有更好的方法来执行上述任务?我想到了 MYSQL 分区。但是,我没有固定的分区。日期会发生变化,因此我每天都需要两个新分区。

【问题讨论】:

    标签: mysql performance replication


    【解决方案1】:

    原则上您的方法是可以的,但是这个概念是基于较小的表性能更高的想法。这意味着您的查询正在对数据运行全表扫描 - 即您没有正确配置索引。

    我建议您首先修复查询的性能。

    如果您仍然需要将内容排除在热数据表之外,那么您应该寻求将任何插入历史表作为批量操作而不是一次一行 - 这将使表和索引保持健康状态.这可以按照 Cristian 的建议在批处理操作中完成,或者您可以使用随机方法(在源表中使用状态变量)。例如类似...

    AFTER INSERT ON mytable
    IF (0.95<RAND()) THEN
       UPDATE mytable SET control=CONNECTION_ID()
       WHERE control IS NULL;
       INSERT INTO backuptable (...)
         SELECT .... FROM mytable
         WHERE control=CONNECTION_ID();
       UPDATE mytable SET control=-1
       WHERE control=CONNECTION_ID();
     END IF;
    

    另外一个考虑是你在写入历史表时会生成一个新的 id:为什么?

    【讨论】:

    • 我实际上从历史记录表中删除了新的 id,因为它没有任何用途。
    【解决方案2】:

    我会让它更简单。创建一个使用“TODAY_DATE”执行这两个查询的每日 cron:

    create table if not exists featured_deal_new like featured_deal
    rename table featured_deal to featured_deal_history_TODAY_DATE, featured_deal_new to featured_deal
    

    会发生什么:(重命名表非常快)。您每天都会有一个历史记录表。

    之后可以随意组合历史表格

    insert into featured_deal_history... select * from featured_deal_history_TODAY_DATE

    Drop table featured_deal_history_TODAY_DATE
    

    这样您就不会降低主表中插入的性能。

    【讨论】:

      猜你喜欢
      • 2015-12-18
      • 2021-09-08
      • 1970-01-01
      • 2021-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-03
      • 2015-07-10
      相关资源
      最近更新 更多