从mysql innodb中删除大量数据

时间:2010-05-12 04:28:32

标签: sql mysql innodb

我需要在生产数据库中删除大量数据,生成数据库的大小约为100GB。如果可能的话,我想尽量减少停机时间。

我的删除选择标准可能是

  

DELETE * FROM POSTING WHERE USER.ID = 5 AND UPDATED_AT< 100

删除它的最佳方法是什么?

  • 建立索引?
  • 编写一个顺序脚本,一次通过行1000分页删除?

4 个答案:

答案 0 :(得分:7)

您可以尝试使用mysql doc中提到的方法:

  1. 选择不要删除的行到与原始表格具有相同结构的空表中:

    INSERT INTO t_copy SELECT * FROM t WHERE ...;

  2. 使用RENAME TABLE以原子方式移动原始表格并将副本重命名为原始名称:

    RENAME TABLE t TO t_old,t_copy TO t;

  3. 删除原始表:

    DROP TABLE t_old;

答案 1 :(得分:2)

如果可能的话,至少在此操作期间使用行级二进制日志记录而不是语句级二进制日志记录(它减少了锁的数量)。批量执行删除(1000是一个体面的大小)。使用主键作为条件,通过主键删除每个批次和订单(以便删除彼此物理上相近的行)。

答案 2 :(得分:1)

最好的方法是使用LIMIT子句(10000项)逐步删除,但不应用排序。这将允许MySQL更频繁地刷新结果,并且转换不会很大。您可以使用已安装的任何具有mysql连接器的编程语言轻松完成此操作。请务必在每个陈述后提交。

索引肯定会有所帮助,但是在100 GB的表上构建它也需要一段时间(无论如何,当你将来要重用索引时,它是值得创建的)。顺便说一句,您当前的查询是不正确的,因为引用了此处未列出的表USER。您应该小心索引,以便优化器可以从使用它中受益。

答案 3 :(得分:0)

前段时间我想从表中删除超过99%的数据。我正在删除的表是一个有超过2.5亿行的会话表,我只想要最近的500K。我想出的最快的方法是在另一个表中选择我想要的500,000行。删除旧表并重命名新表以替换已删除的表。这比执行必须选择记录和重建表的常规删除快约100倍。

如果您使用InnoDB和innodb_file_per_table = 1,这还有一个减少表文件大小的额外好处,因为InnoDB表永远不会缩小。