我想从MySql DB中的大表(~500K记录)中删除大量记录(~200K)。
我希望尽可能高效地进行此调用,因为我不希望数据库在执行调用时变得“无响应”。
我需要删除“早于10天”的记录(根据created_at
列),目前我使用:
delete from table_name where created_at < DATE_SUB(CURDATE(),INTERVAL 10 DAY)
如果表有帮助,该表还有一个主键id
。
有什么想法吗?
答案 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语句使用主键。