MySQL-按日期对数据库或表进行分区,以便快速清理

MySQL-按日期对数据库或表进行分区,以便快速清理,mysql,database,partitioning,Mysql,Database,Partitioning,我有一个非常大的数据库。一列是时间戳,每天我都要删除30天或更长时间的任何行。问题是,随着时间的推移,数据库删除行并插入新行,新行可能会插入到先前被删除行占用的位置,从而创建一个关于时间戳的碎片数据库。当我去清理数据库时,一个碎片化的数据库需要花费大量的时间来清理,因为MySQL必须遍历整个数据库 我想采用的一种解决方案是每天创建单独的分区,甚至是单独的数据库,这样每天都会自动创建一个新分区来填充,并且自动删除每30天以上的旧分区 我正在研究PARTITION命令,它看起来像是对一个表进行了追溯

我有一个非常大的数据库。一列是时间戳,每天我都要删除30天或更长时间的任何行。问题是,随着时间的推移,数据库删除行并插入新行,新行可能会插入到先前被删除行占用的位置,从而创建一个关于时间戳的碎片数据库。当我去清理数据库时,一个碎片化的数据库需要花费大量的时间来清理,因为MySQL必须遍历整个数据库

我想采用的一种解决方案是每天创建单独的分区,甚至是单独的数据库,这样每天都会自动创建一个新分区来填充,并且自动删除每30天以上的旧分区

我正在研究
PARTITION
命令,它看起来像是对一个表进行了追溯性分区。我想从一开始就自动完成

有人对如何做到这一点有什么见解吗

编辑: 我正在使用snort和barnyard清理数据库。我在一份工作中一直在做类似的事情:

use YOUR-SNORT-DB-NAME;
DELETE FROM event WHERE timestamp < DATE_SUB(NOW(),INTERVAL 28 DAY);
DELETE FROM data    USING data    LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM iphdr   USING iphdr   LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM icmphdr USING icmphdr LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM tcphdr  USING tcphdr  LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM udphdr  USING udphdr  LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM opt     USING opt     LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM acid_event USING acid_event LEFT OUTER JOIN event USING (sid,cid) WHERE event.sid IS NULL;
DELETE FROM ag USING acid_ag_alert AS ag LEFT OUTER JOIN event AS e ON ag.ag_sid=e.sid AND ag.ag_cid=e.cid WHERE e.sid IS NULL;
OPTIMIZE TABLE event, data, iphdr, icmphdr, tcphdr, udphdr, opt, acid_event, acid_ag_alert
使用您的-SNORT-DB-NAME;
从时间戳
如果数据库非常大,这似乎不切实际。它似乎也没有使用索引


我不是数据库专家,所以我想知道如何修改模式或清理脚本以提高性能。

是的,
分区对于从表中清除“旧”数据非常有用。这是
分区的极少数用途之一。并使用
按范围划分(到_天(…)
,而不是
按散列划分
,等等。有关执行
更改的详细信息和示例代码,请参阅[我的博客]。它建议使用大约32个“每日”分区

不要在InnoDB表上使用
优化表
;这种努力几乎总是不值得的

您在所有表上都有一个复合
索引(sid,cid)


如果其他表上的
删除操作
侵入性太强(因为锁太长),请参阅,以了解侵入性较小的选项的讨论。

是的,
分区
有助于从表中清除“旧”数据。这是
分区的极少数用途之一。并使用
按范围划分(到_天(…)
,而不是
按散列划分
,等等。有关执行
更改的详细信息和示例代码,请参阅[我的博客]。它建议使用大约32个“每日”分区

不要在InnoDB表上使用
优化表
;这种努力几乎总是不值得的

您在所有表上都有一个复合
索引(sid,cid)


如果其他表上的
删除操作
侵入性太强(因为锁太长),请参阅以了解侵入性较小的选项的讨论。

如果您的列已被索引,您不应该看到任何性能影响。是什么让您认为您有一个碎片化的数据库?也许您应该阅读分区的用途使用按日期分区-然后您可以轻松地删除包含旧数据的分区,这是即时操作。如果您的列被索引,您不应该看到任何性能影响。是什么让您认为您有一个碎片化的数据库?也许您应该阅读分区的用途使用按日期分区-然后您可以轻松地删除包含旧数据的分区,这是即时操作。