【问题标题】:MySQL Prune old rows to one per dayMySQL 每天将旧行修剪为一个
【发布时间】:2016-05-04 02:46:24
【问题描述】:

我有一个巨大的 MySQL 表,它每秒增长大约 90 行,每 4 小时有 130 万行随时间戳转储到那里

user(varchar)   | created_at(timestamp)
----------------------------
user 1          | 2016-01-27 08:00:00
user 2          | 2016-01-27 08:00:00
user 3          | 2016-01-27 08:00:00
...
user 1          | 2016-01-27 12:00:00
user 2          | 2016-01-27 12:00:00

等等...将超过一个月的数据修剪为每天只有一行的最佳方法是什么?

00:00 总是有行,所以我在想一些类似的事情

created_at >= date + 00:00 and created_at < date + 19:59

select user, max(created_at) from table where created_at = date group by username

【问题讨论】:

  • 每天只有一行是什么意思?
  • 所以每 4 小时我会为所有用户获取一些数据,但一个月后我不需要那么精细,每天只需要一个,所以理想情况下只保留当天的第一次导入。分钟一秒始终为 0,因为它是导入开始的时间,它在 PHP 中完成为 date('Y-m-d H:00:00')
  • 你实际上可以在mysql上使用events,你可以安排这些事件来删除某个表并在每天的特定时间运行该事件
  • 使用limit 1 或group by created_at 来保持单条记录。
  • 我想我已经成功了,虽然select count(id) from teamsarchive where created_at < DATE_SUB(NOW(), INTERVAL 30 DAY) and HOUR(created_at) = 00

标签: mysql


【解决方案1】:

对于如此大量的数据,您可能希望使用分区来管理数据,因为在大型表上运行带有过滤器的删除语句可能需要很长时间。当您按月创建分区时,删除分区非常快。但这会删除该月的数据,因此您可能需要在删除分区之前将用户摘要存储在另一个表中。

【讨论】:

    【解决方案2】:

    好吧,我玩了一些游戏,所以我会为其他想要修剪数据的人发布此内容。

    created_at 必须是 TIMESTAMP

    delete from `table` where `created_at` < DATE_SUB(NOW(), INTERVAL 30 DAY) and HOUR(created_at) = 00
    

    这将删除小时设置为 00 的所有行,但如果您需要更大的灵活性,您可以这样做

    delete from `table` where `created_at` < DATE_SUB(NOW(), INTERVAL 30 DAY) and HOUR(created_at) between 0 and 4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-16
      • 1970-01-01
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      • 2021-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多