当前位置:首页 > 文章列表 > 数据库 > MySQL > 浅谈MySQL如何优雅的做大表删除

浅谈MySQL如何优雅的做大表删除

来源:脚本之家 2023-02-20 18:36:14 0浏览 收藏

本篇文章向大家介绍《浅谈MySQL如何优雅的做大表删除》,主要包括MySQL大表删除,具有一定的参考价值,需要的朋友可以参考一下。

随着时间的推移或者业务量的增长,数据库空间使用率也不断的呈稳定上升状态,当数据库空间将要达到瓶颈的时候,可能我们才会发现数据库有那么一两张的超级大表!他们堆积了从业务开始到现在的全部数据,但是90%的数据都是没有业务价值的,这时候该如何处理这些大表?

既然是没有价值的数据,我们通常一般会选择直接删除或者归档后删除两种,对于数据删除的操作方式来说又可分为两大类:

  • 通过truncate直接删除表中全部数据
  • 通过delete删除表中满足条件记录

一、Truncate操作

从逻辑意义上来讲,truncate操作就是删除表中所有记录行,但是又与delete from table_name wehre 1=1这种操作不一样。MySQL为了提高删除整张表数据的性能,truncate操作其本质上其实是先drop table然后在re-create table。也真因如此,truncate操作是一个不可回滚的DDL操作。

1.1 MySQL truncate 都做了哪些操作?

  • truncate操作实际上分为drop、re-create两步
  • drop操作的第一个阶段,是对Buffer pool页面进行清除的过程,将表相关的数据页从flush链中删除,而不需要做flush操作。该步骤的瓶颈点主要在于flush队列的删除操作必须持有对应buffer pool instance的锁并进行遍历搜索,如果buffer pool instance比较大且flush链中需要删除的数据页很多,该操作会导致其他事务在获取buffer pool instance的锁时被阻塞,从而影响数据库的性能
  • drop操作的第二个阶段,是删除ibd磁盘文件的过程。删除数据库物理文件越大I/O资源消耗越大,删除操作耗时越久
  • re-create操作阶段,只要删除表的.frm文件完好无损,在drop table之后就可以按照原表结构信息进行重建,重建后表的auto_increment值会被重置

1.2 如何优化truncate操作带来的资源消耗?

  • 对于truncate操作中的drop表第一阶段,当分配给MySQL实例的innodb_buffer_pool_size超过1GB时,合理的设置innodb_buffer_pool_instances参数,提高并发的同时也变相的减少扫描buffer pool instance时锁资源占用耗时
  • 对于truncate操作中的drop表第二阶段,在删除对应表之前,先对改表的.ibd文件创建一个硬连接,加快MySQL层面的drop操作执行效率,减少对数据库层面的性能损耗。后续手动对操作系统层面我们做的硬连接进行清理

二、Delete操作

2.1 MySQL delete 都做了哪些操作?

  • 根据where条件对删除表进行索引/全表扫描,检查是否符合where条件,该阶段会对扫描中所有行进行加锁。该阶段是最大的资源消耗隐患,若表的数据量大且delete操作无法有效利用索引减少扫描数据量,该步骤对于数据库带来的锁争用、cpu/io资源的消耗都是巨大的
  • 对不能够被where条件匹配的行施加的锁会在条件检查后予以释放,InnoDB仅锁定需要删除的行。这可以有效地降低锁争用,但是我们仍需要关注的一点是,一次性删除大批量的数据,该操作将会产生巨大的binlog事务日志,这对于MySQL自身以及主从架构中的从库都是不友好的,可能带来叫的复制延迟。

2.2 如何优化delete操作?

  • delete全表删除操作需要谨慎,可考虑使用truncate操作
  • delete … where … 中,where过滤条件尽量保证可有效利用索引减少数据扫描量,避免全表扫描
  • 对于大批量数据删除且where条件无索引的情况,delete操作可额外增加自增长主键或者含索引的时间字段,进行分批删除操作,每次删除少量数据,分多批次执行。
  • 对于保留近期数据删除历史数据的经典场景,可创建同结构的xxx_tmp表并通过insert xxx_tmp select …操作将需要的数据保留至tmp表中、然后通过rename操作将当前业务表xxx替换为xxx_bak表,xxx_tmp表替换为当前业务表名xxx,后续手动删除无用的大表xxx_bak

2.3 delete常见的两个场景

2.3.1 delete where条件无有效索引过滤

比较常见的一个场景是,业务上需要删除t1 condition1=xxx的值,condition字段无法有效利用索引,这种情况下我们通常的做法是:

  • 查看当前表结构中可有效利用的索引,尽量是表的自增长主键或者时间索引字段
  • 有效利用自增长主键索引或者时间索引,将delete操作添加索引字段的范围过滤,每次删除少量数据,分多批次执行。具体分批需要根据业务实际进行评估,避免一次性删除大批量数据。
-- 利用自增长主键索引
delete from t1 where condition1=xxx and id >=1 and id =50000 and id = '2021-01-01 00:00:00' and create_time = '2021-02-01 00:00:00' and create_time 

2.3.2 保留近期数据删除历史数据

比较常见的一个场景是,需要仅保留t1表近3个月数据,其余历史数据删除,我们通常的做法是:

创建一张t1_tmp表用来临时存储需要保留的数据

create table t1_tmp like t1;

根据有索引的时间字段,分批次的将需要保留的数据写入t1_tmp表中,该步骤需要注意的是,最后一批次时间的操作可暂时不处理

-- 根据实例业务数量进行分批,尽量每批次处理数据量不要太大
insert into t1_tmp select * from t1 where create_time >= '2021-01-01 00:00:00' and create_time = '2021-02-01 00:00:00' and create_time = '2021-03-01 00:00:00' and create_time 

通过rename操作将当前业务表t1替换为t1_bak表,t1_tmp表替换为当前业务表名t1,被删除表若有频繁的DML操作,该步骤会造成短暂的业务访问失败

alter table t1 rename to t1_bak;
alter table t1_tmp rename to t1;

将最后一批次数据写入当前业务表,该步骤的目的是为了减少变更操作流程中的数据丢失

insert into t1 select * from t1_bak where create_time >= '2021-03-01 00:00:00' and create_time 

在rename操作步骤中,还有一点我们需要关注的是,变更表主键是自增长还是业务唯一的uuid,若为自增长主键,我们还需要注意修改t1_tmp表的自增长值,保证最终设置值包含变更期间数据写入

alter table t1_tmp auto_increment={t1表当前auto值}+{变更期间预估增长值}

三、Truncate/Delete优劣势对比

操作类型 描述 优势 劣势
Truncate 表的全量删除操作 无需扫描表数据,执行效率高,直接进行物理删除,快速释放空间占用 DDL操作无法进行回滚,无法按条件进行删除
Delete 根据指定条件进行过滤删除操作 可根据指定条件进行过滤删除 删除效率依赖where条件的编写,大表删除会产品大量的binlog且删除效率低,删除操作可能出现较多的碎片空间而不是直接释放空间占用

以上就是《浅谈MySQL如何优雅的做大表删除》的详细内容,更多关于mysql的资料请关注golang学习网公众号!

版本声明
本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除
MySQL too many connections错误的原因及解决MySQL too many connections错误的原因及解决
上一篇
MySQL too many connections错误的原因及解决
MySQL mysqladmin客户端的使用简介
下一篇
MySQL mysqladmin客户端的使用简介
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 笔灵AI生成答辩PPT:高效制作学术与职场PPT的利器
    笔灵AI生成答辩PPT
    探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
    15次使用
  • 知网AIGC检测服务系统:精准识别学术文本中的AI生成内容
    知网AIGC检测服务系统
    知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
    24次使用
  • AIGC检测服务:AIbiye助力确保论文原创性
    AIGC检测-Aibiye
    AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
    30次使用
  • 易笔AI论文平台:快速生成高质量学术论文的利器
    易笔AI论文
    易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
    42次使用
  • 笔启AI论文写作平台:多类型论文生成与多语言支持
    笔启AI论文写作平台
    笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
    35次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码