MySQL删除大批量数据优化

背景:

经过实验,每次删除400万条要花1.5 - 3小时,而且是越到后面越慢,正常的话,需要大约102个小时,大约4天半时间。这在生产环境下是不能接受的。

产生原因:

每次删除记录,数据库都要相应地更新索引,查询MySQL官方手册得知删除数据的速度和创建的索引数量是成正比的;这是很慢的IO操作,而且后面索引碎片越来越多,就更慢,这就是为什么一开始只花1.5小时,后面要3小时才能删除400万条记录的原因。

【注意】记得在删除的时候不要在记录日志的模式下面,否则日志文件就要爆了。

方法一:

MySQL原文处理方案链接:https://dev.mysql.com/doc/refman/8.0/en/delete.html
在这里插入图片描述
简单翻译下:
删除大表的多行数据时,会超出innod block table size的限制,最小化的减少锁表的时间的方案是:
1、选择不需要删除的数据,并把它们存在一张相同结构的空表里 :INSERT INTO t_copy SELECT * FROM t WHERE … ;
2、重命名原始表,并给新表命名为原始表的原始表名: RENAME TABLE t TO t_old, t_copy TO t;
3、删掉原始表:DROP TABLE t_old;

方法二:

在实际操作过程中,如果不在乎时间(利用下班时间定时删除),可以利用limit分批次删除:

假设有一个表(syslogs)有1000万条记录,需要在业务不停止的情况下删除其中statusid=1的所有记录,差不多有600万条, 直接执行 DELETE FROM syslogs WHERE statusid=1 会发现删除失败,因为lock wait timeout exceed的错误。

因为这条语句所涉及的记录数太多,因此我们通过LIMIT参数分批删除,比如每10000条进行一次删除,那么我们可以利用MySQL这样的语句来完成:
DELETE FROM syslogs WHERE status=1 ORDER BY statusid LIMIT 10000;
然后分多次执行就可以把这些记录成功删除。

注:

  • 执行大批量删除的时候注意要使用上limit。因为如果不用limit,删除大量数据很有可能造成死锁。
  • 如果delete的where语句不在索引上,可以先找主键,然后根据主键删除数据库。
  • 平时update和delete的时候最好也加上limit 1 来防止误操作。

***注:有参考其他论坛,博客,文章仅供自我学习; ***

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在MySQL中新增大批量数据,可以通过以下几种方法来实现。 第一种方法是使用INSERT INTO语句。可以将需要插入的数据按照一定的格式(例如CSV格式)保存在一个文本文件中,然后使用LOAD DATA INFILE语句将文本文件中的数据直接导入到MySQL数据库中。这个方法的好处是可以快速插入大量数据,但需要事先将数据保存在文本文件中。 第二种方法是使用INSERT INTO语句的批量插入形式。可以将多个INSERT INTO语句合并为一个INSERT INTO语句,并使用VALUES子句一次性插入多条数据。这种方法比较适用于数据较小的情况,不需要保存为文本文件。 第三种方法是使用INSERT INTO SELECT语句。可以先创建一个临时表,将需要插入的数据保存到临时表中,然后使用INSERT INTO SELECT语句将临时表中的数据插入到目标表中。这种方法比较适用于需要对插入的数据进行一定的处理或筛选的情况。 无论使用哪种方法,对于大批量数据的插入,还可以考虑以下几点优化: 1. 在插入之前,将目标表的索引和约束暂时禁用,以提高插入的速度; 2. 设置合适的事务大小,将多个插入操作批量提交,减少事务的开销; 3. 根据数据的特点,合理选择合适的插入顺序,以提高插入的效率; 4. 使用多线程或并行插入提高并发处理能力。 总之,根据具体的需求和场景,可以选择合适的方法和优化策略来实现MySQL大批量数据插入。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值