从大表中删除大量记录的有效方法

时间:2011-03-25 08:47:32

标签: mysql performance

我想从MySql DB中的大表(~500K记录)中删除大量记录(~200K)。

我希望尽可能高效地进行此调用,因为我不希望数据库在执行调用时变得“无响应”。 我需要删除“早于10天”的记录(根据created_at列),目前我使用:

delete from table_name where created_at < DATE_SUB(CURDATE(),INTERVAL 10 DAY)

如果表有帮助,该表还有一个主键id

有什么想法吗?

3 个答案:

答案 0 :(得分:9)

我面临同样的挑战。 如果没有主键,但created_at字段上有索引,则无法从100Mio行表(InnoDB)中删除最旧的10Mio条目。由于表格在线并且仍然接收INSERTS,因此锁定溢出始终失败。

为了解决这个问题,我创建了一个以递增方式处理作业的存储过程:

mysql> CREATE PROCEDURE delete_accesslog_incrementally()
-> MODIFIES SQL DATA
-> BEGIN
-> REPEAT
-> DELETE FROM tbl_name
-> WHERE created_at < DATE_SUB(CURDATE(),INTERVAL 10 day)
-> LIMIT 20000;
-> UNTIL ROW_COUNT() = 0 END REPEAT;
-> END $$

这仍然会运行很长一段时间,但不会损害仍在使用该表的并发INSERTS。

答案 1 :(得分:4)

您有一个WHERE条件,在created_at字段上添加一个索引。

答案 2 :(得分:4)

你可以试试这个:

1)首先找到所需日期的第一个id值:

select id from table_name where created_at = DATE_SUB(CURDATE(),INTERVAL 10 DAY) LIMIT 1;

2)接下来批量删除:

DELETE FROM table_name where id<"id_found_on_step_1" LIMIT 1000; 

在id_found_on_step_1上输入您在步骤1中找到的ID值。 您可以尝试10000或低于1000.这取决于每个删除命令将花费多少时间。

此DELETE应该更快,因为其WHERE语句使用主键。