MYSQL大表删除
1. 选场景选策略
- 整张表的数据全部删除
如果是整张表的数据全部清空、删除,这种场景倒是非常简单,TRUNCATE TABLE肯定是最快的。反而用DELETE处理的话,就是一个糟糕的策略。
- 大表中删除一部分数据
删除大表中绝大部分的数据,但是这个绝大部分怎么定义不好量化,所以我们这里就量化为60%。如果删除的数据比例超过60%,就采用下面方法:
-
新 建表TEST_TMP
-
将要保留的数据转移到TEST_TMP
-
将原表TEST重命名为TEST_OLD, 而将TEST_TMP重命名为TEST
-
检查相关的触发器、约束,进行触发器或约束的重命名
-
核对操作是否正确后,原表(TEST_OLD)要么TRUANCATE后,再DROP掉。要么保留一段时间,保险起见。
删除大表中部分数据,如果比例不超过60%:
-
先删除或禁用无关索引(无关索引,这里指执行计划不用到的索引,这里是指对当前DELETE语句无用的索引)。因为DELETE操作属于DML操作,而且大表的索引一般也非常大,大量DELETE将会对索引进行维护操作,产生大量额外的IO操作。
-
用小批量,分批次删除(批量删除比一次性删除性能要快很多)。不要一次性删除大量数据。一次性删除大量记录。会导致锁的粒度范围很大,并且锁定的时间非常长,而且还可能产生阻塞,严重影响业务等等。而且数据库的事务日志变得非常大。执行的时间变得超长,性能非常糟糕。
2. 准备工作
利用 MYSQL 存储过程向表中添加大量测试数据,示例:
3. 落地实践方案
结合本项目的实际,本次选取方案为分批次删除表中数据,首先查出来满足条件的表中数据总数,对总数与每次删除数进行向上取余,得出需执行 DELETE 次数,最终循环执行删除操作。每次删除总数结合实际进行选取,本案例选取每次删除 1 万条数据。
- 总数方案1
- 总数方案2
- 槽方案
注意:本例中需注意时间异步问题,应当选取 JAVA8 提供的时间操作类。Calendar 类在使用中需开发者自行解决异步问题。
引用:https://blog.csdn.net/weixin_42302384/article/details/114587546?utm_term=calendar线程安全的&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allsobaiduweb~default-6-114587546&spm=3001.4430
测试:此次测试分为本地本机测试与远程数据库服务器测试,其中主要考虑因素为本机与服务器机器性能之间的差异,网络原因不在测试考虑范围内。
以下测试均是批量删除,每次删除数据为 1 万条(本地本机数据库):
亿数据删除十万
亿数据删除百万
千万数据删除十万
千万数据删除百万
百万数据删除十万
每次删除数据为 10 万条(服务器数据库),数据库最大连接时长3分:
百万数据删除十万
千万数据删除十万
八千万数据删除十万
亿数据删除十万
引用:
https://www.jb51.net/article/207999.htm
http://c.biancheng.net/mysql/85/