Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何高效的批量删除亿级大表数据

如何高效的批量删除亿级大表数据

原创
作者头像
小勇DW3
发布于 2019-01-02 11:15:33
发布于 2019-01-02 11:15:33
4.6K0
举报
文章被收录于专栏:小勇DW3小勇DW3

最新项目一直出现线上问题,定位原因看到是由于表数据过大导致的,现在有个登录表,登录游戏玩家每次登录的信息,久而久之,这几个表的数据量达到了两亿多条。每天都在上报,采集,由于没有定期删除,数据大量累积。大概有一年左右的数据,一个表的数据已经达到亿级别的。这样算下来,一个表的数据至少是几十GB了。因此需要删除过期的数据,暂时保留近三个月的统计数据。

解决方案:

基本每个表都有个字段叫create_time或者collect_time的字段,只要删除这个字段三个月之前的数据就ok了

delete from table_name where create_time < '2017-04-06'

只要执行这句SQL应该就可以了

遇到的问题:

The total number of locks exceeds the lock table size in MySQL

因为需要删除的数据太大,mysql给的buffer好像只有8MB左右(网上搜到的)

后面找到DBA帮忙看,问这个表建了索引没有

show index from table_name

通过查看索引,我们在create_time和collect_time上是建了索引的,索引类型是BTree,ASC。这里我们用的Mysql引擎是InnoDb

delete from table_name where create_time < '2017-07-06' order by create_time asc limit 10000

接着,我想用order by + limit实现删除,还是出现了上面的错误

后面DBA提示我说,为啥不用ID删除,说按id删除,速度和按索引列删除,不是一个数量级的

接着我想到了拆分一下。

最终解决方案:

找出符合条件的create_time和collect_time的最大ID

select max(id) from table_name where create_time < '2017-04-06'

这里千万左右的数据大概需要10多秒

接着按id删除,一次删除10k,循环删除

delete from table_name where id < maxId limit 10000

直到把过期的时间删除完成

这里我没有msyql服务器的权限,通过java客户端连接删除,使用的spring jdbcTemplate这个接口

另外,这里一次删除10k还有个原因是,事务太大,影响其他服务的运行

还用到的技术,就是使用线程池来执行sql删除,实现异步删除。和同事吃饭的时候,同事也提供了一个解决方案,每次删一秒的数据,这样一次次的删。看了一下数据,一秒的数据基本在几十万,左右,这样不太好控制数据量大小。还是通过主键id + limit 10k这里稳妥一点。

还有一点就是,为了怕压到mysql服务器,这里线程池删除的时候回sleep(1000),阻塞1s再删除,减轻mysql服务器的压力

今天搞了一下数据删除这一点东西,感觉mysql水很深,比如一个select count(*)的执行过程,select from table_name order by id limit 的过程,索引,各种连接,引擎的工作原理。走的时候还有点没有调完,明天应该可以搞定这些了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
数据库之MySql建议收藏
   mysql是一种开放源代码的关系型数据库管理系统(RDBMS),是使用最常用的数据库管理语言–结构化查询语言(SQL)进行数据库管理。
全栈程序员站长
2022/07/14
9230
MySQL深入研究:表数据操作
可以看到数据已经插入进来,没有填充数据的列已NULL填充,关于这一点,我们可以在创建表的时候通过DEFAULT来指定默认值,就是在这个时候使用的
IT大咖说
2021/07/19
5830
MySQL:想实现sql语句进行批量删除数据库或表,而引发的熬夜探究
了解到数据库或表的信息都保存在MySQL内置的 information_schema数据库的SCHEMATA表中,因此是否可以通过like查询information_schema中的相关表名,拼接SQL,进行批量删除。
鲲志说
2025/04/07
1010
MySQL:想实现sql语句进行批量删除数据库或表,而引发的熬夜探究
【数据库系列】你想要的sql全都有plus
有一天突然发现【数据库】你想要的sql全都有 阅读量破300了,非常高兴,当天流量不断飙升,也不断有人关注,然后就是是一个幸运的开始。
用户9913368
2022/08/13
4830
【数据库系列】你想要的sql全都有plus
小弟问我:为什么MySQL不建议使用delete删除数据?
我负责的有几个系统随着业务量的增长,存储在MySQL中的数据日益剧增,我当时就想现在的业务方不讲武德,搞偷袭,趁我没反应过来把很多表,很快,很快啊都打到了亿级别,我大意了,没有闪,这就导致跟其Join的表的SQL变得很慢,对的应用接口的response time也变长了,影响了用户体验。
敖丙
2020/11/24
4.5K0
小弟问我:为什么MySQL不建议使用delete删除数据?
【Mysql】mysql命令常用语句[通俗易懂]
参考文档 https://www.cnblogs.com/dongling/p/5710643.html
全栈程序员站长
2022/10/04
7580
【Mysql】mysql命令常用语句[通俗易懂]
【MySQL】详解MySQL中表的基本插入、删除、查询、修改语句
由于 主键 或者 唯一键 对应的值已经存在而导致插入失败的时候,如果我们想说我们要插入的这条记录无论主键或者是唯一键冲突都帮我完成插入,可以选择性的进行同步更新操作语法。
用户10923276
2024/10/26
3570
8 种常被忽视的 SQL 错误用法
好吧,可能90%以上的 DBA 解决该问题就到此为止。但当 LIMIT 子句变成 “LIMIT 1000000,10” 时,程序员仍然会抱怨:我只取10条记录为什么还是慢?
Java编程指南
2019/08/02
3430
8种常被忽视的SQL错误用法
分页查询是最常用的场景之一,但也通常也是最容易出问题的地方。比如对于下面简单的语句,一般 DBA 想到的办法是在 type, name, create_time 字段上加组合索引。这样条件排序都能有效的利用到索引,性能迅速提升。
Bug开发工程师
2018/12/05
5670
Mysql进阶索引篇03——2个新特性,11+7条设计原则教你创建索引
前 言 🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端 🍌 专栏简介:mysql进阶,主要讲解mysql数据库进阶知识,包括索引、分库分表等 🌰 文章简介:本文将介绍索引的分类、创建、删除,Mysql8.0中索引的新特性,索引的设计原则 🍎 三连、互关必回,不回可私信哟 🥛 相关链接:大厂SQL面试真题大全 1、索引的声明与使用 1.1. 索引的分类 先介绍下索引的分类,方便后续介绍索引的创建与设计。 按照功能逻辑划分,索引主要有:普通索引、唯一索引、主键索引、全
半旧518
2022/10/26
1.3K0
Mysql进阶索引篇03——2个新特性,11+7条设计原则教你创建索引
这些SQL错误用法,如果经常犯,说明你的水平还很low...
今天来分享几个MySQL常见的SQL错误(不当)用法。我们在作为一个初学者时,很有可能自己在写SQL时也没有注意到这些问题,导致写出来的SQL语句效率低下,所以我们也可以自省自检一下。
程序员白楠楠
2020/11/29
8510
MySQL数据库、数据表、字段、数据的增删改查
查询数据库列表 show databases ; 查询某一个数据库的信息: show create database 数据库名称;
菲宇
2022/12/02
4.4K0
【数据库】你想要的sql全都有
我很早就想整理一波常用sql,这不就搞起来了。 先执行初始化sql,后面的就可以在这个数据表上面练习了,拿来即用。 我后面会慢慢完善这个大一统的sql集合的,感兴趣的话可以持续关注呀~ /* 目录 数据准备 user表相关 选择数据库 设计表结构 索引相关 增删改查 条件查询 时间查询 连接查询 存储过程 查询数据库大小 设置变量 系统变量 时间函数 其它函数 随机数 **/ -- 数据准备---------------------------------------- CREATE TABLE
用户9913368
2022/08/13
4390
【MySQL】表数据的CRUD操作详解
CRUD : Create(创建), Retrieve(读取),Update(更新),Delete(删除)
用户11316056
2025/02/26
1040
【MySQL】表数据的CRUD操作详解
[1183]Clickhouse数据表&数据分区partition&数据生命周期操作
也可以直接去看官方文档:https://clickhouse.com/docs/zh/sql-reference/statements/alter/column
周小董
2023/10/10
1.6K0
MYSQL数据库-基本操作
MYSQL数据库-基本操作 零、前言 表的增删改查 一、Create 1、插入 2、更新和替换 二、Retrieve 1、SELECT 查询 2、WHERE 条件 3、结果排序 4、筛选分页结果 三、Update 四、Delete 1、删除数据 2、截断表 五、插入查询结果 六、聚合函数 七、group by 零、前言 本章主要讲解表的基本操作 表的增删改查 CRUD : Create(创建), Retrieve(读取),Update(更新),Delete(删除) 一、Create 创建语法:
用户9645905
2022/11/15
1K0
MYSQL数据库-基本操作
MySQL中,21个写SQL的好习惯
本文公众号来源:捡田螺的小男孩 作者:捡田螺的小男孩 本文已收录至我的GitHub
Java3y
2020/11/11
9750
MySQL中,21个写SQL的好习惯
【MySql】基本查询
这是由于sql的执行顺序影响:这里的执行顺序非常重要,这里无法使用别名,很简单:这是因为先执行from,先从哪个表里筛选数据,筛选的时候,得先设定筛选条件
平凡的人1
2023/10/15
2360
【MySql】基本查询
PT-archiver数据归档-重构版
一张大表,我们姑且说1亿条记录,原表我要保存近7天的数据。Percona pt-archiver工具是这样做的,逐条把历史数据insert到归档表,同时删除原表数据。7天数据比如说只有10万行,那么原表会直接删除9990万行记录,操作成本太高,固需要考虑重构。
DBA实战
2024/09/06
890
PT-archiver数据归档-重构版
8种常见SQL错误用法
分页查询是最常用的场景之一,但也通常也是最容易出问题的地方。比如对于下面简单的语句,一般 DBA 想到的办法是在 type, name, create_time 字段上加组合索引。这样条件排序都能有效的利用到索引,性能迅速提升。
Java团长
2019/06/03
6850
相关推荐
数据库之MySql建议收藏
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档