今天接到一位开发同学的数据操作需求,需求看似很简单,需要执行下面的SQL语句:

delete from test_track_log where log_time < '2019-1-7 00:00:00';

看需求描述是因为查询统计较差,希望删除一些历史数据。

带着疑问我看下了表结构:

CREATE TABLE `test_track_log` (

`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',

`uid` int(11) unsigned NOT NULL DEFAULT '' COMMENT '用户ID',

...

`log_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录时间',

PRIMARY KEY (`id`),

KEY `idx_uid_fsm_log` (`uid`,`fsm_id`,`log_time`)

) ENGINE=InnoDB AUTO_INCREMENT=125082604 DEFAULT CHARSET=utf8 COMMENT='记录测试账号的任务轨迹'

看自增列的情况,这个表的数据量有近1亿条记录了,暂且不说数据量带来的额外影响,单说这个需求,你会发现这是一个陨石坑。

简单验证了下,数据量确实在亿级别。

select count(id) from tgp_db.tgp_track_log

+-----------+

| 125082603 |

+-----------+

1 row in set (1 min 26.63 sec)

如果老老实实执行了,估计我下午就不用干别的了。

显然这个需求是一个模糊需求,业务方希望清理数据,但是实现方式缺不合理。

如果我们使用truncate的操作,这样看来目前是比较合适的。

同时在做数据清理的时候,势必要考虑备份数据,而和业务方确认,数据可以不用备份,但是从数据库层面来说,是需要的。

在操作前进行细致的沟通,发现业务方还是会希望参考近些天来的数据,尤其是当天的数据,所以这个操作还是需要谨慎。

这里有两个坑:

第一是业务方再三确认不需要备份,但是如果删除了数据之后,发生了意料之外的故障,需要恢复数据,而DBA没法恢复,那么这个锅我们背不住。

第二是业务方再三确认删除的逻辑是正确的,但是他们不负责数据操作的性能问题,我们如果不去审核而为了执行而执行,那么造成性能故障之后,很容易造成需求的分歧。

所以这件事情的本质很简单,清理数据,对业务影响最小,保留指定范围的数据。

这种情况下单纯的DML语句是搞不定了,我们需要想一些办法,这里有一个技巧,也是我非常喜欢MySQL的一个亮点特性,即MySQL可以很轻松的把一个库的表迁移到另外一个数据库,这种操作的代价就好像把一个文件从文件夹1拷贝到文件夹2。

一个初版的实现如下:

create table test_db.test_track_log_tmp like test_db.test_track_log;

alter table test_db.test_track_log rename to test_db_arch.test_track_log;

alter table test_db.test_track_log_tmp rename to test_db.test_track_log;

这种操作看起来很简单,但是也存在一些问题,一个是在切换的过程中,如果写入数据是会丢失数据的,即数据已经入库,这里通过rename丢失数据。

第二个是这个操作不够简洁。怎么改进呢,我们可以把rename的操作玩得更溜。

mysql> create table test_db_arch.test_track_log like test.test_track_log;

mysql> RENAME TABLE test.test_track_log TO test_db_arch.test_track_log_bak,

test_db_arch.test_track_log TO test.test_track_log,

test_db_arch.test_track_log_bak TO test_db_arch.test_track_log;

Query OK, 0 rows affected (0.02 sec)

整个过程持续0.02秒,亿级数据的切换,整体来说效果还是很明显的,也推荐大家在工作中根据适合的场景来应用。

转自

MySQL平滑删除数据的小技巧 https://www.toutiao.com/a6643787647217041924/?tt_from=mobile_qq&utm_campaign=client_share&timestamp=1547273084&app=news_article&utm_source=mobile_qq&iid=26112390770&utm_medium=toutiao_ios&group_id=6643787647217041924

MySQL平滑删除数据的小技巧【转】的更多相关文章

  1. mysql优化, 删除数据后物理空间未释放(转载)

    mysql优化, 删除数据后物理空间未释放(转载) OPTIMIZE TABLE 当您的库中删除了大量的数据后,您可能会发现数据文件尺寸并没有减小.这是因为删除操作后在数据文件中留下碎片所致.OPTI ...

  2. mysql 使用的三个小技巧

    mysql 使用的三个小技巧 快速阅读 Mysql查询工具中如何查询多条语名,Mysql中如何设置变量,Mysql中如何查特定字段,后面再加* Mysql查询工具中如何查询多条语名 默认myslq只能 ...

  3. mysql 在删除数据出现Cannot delete or update a parent row: a foreign key constraint fails 这个该如何解决

    mysql 在删除数据出现Cannot delete or update a parent row: a foreign key constraint fails  这个该如何解决 可以这样解决: S ...

  4. Mysql编写sql语句的小技巧

    1.查询数据(保证查询性能) SELECT * 和 SELECT t.id , t.name:后者性能其实总体优于前者. 2.在查询的时候最好给表起个 别名,方便找到表中要查询的字段.执行sql的进行 ...

  5. 工作中MySql的了解到的小技巧

    工作中MySql的小技巧 1. 跑脚本时,经常遇到有则更新无插入的 逻辑操作:通常情况下,来一波if()判断然后选择 更新还是插入,前两天逛论坛时发现有人在比较REPLACE INTO 和 INSET ...

  6. mysql避免数据库误操作小技巧(转)

    避免混淆开发环境的DB和生产环境的DB这在小公司小团队尤其常见.一个人即负责开发,又管DB.桌面上开了一坨终端,有的是开发的DB,有的是生产的DB.一不留神,就写串了,或者粘贴串了.更郁闷的是,有时候 ...

  7. MySQL数据库删除数据(有外键约束)

    在MySQL中删除一张表或一条数据的时候,出现有外键约束的问题,于是就去查了下方法: SELECT @@FOREIGN_KEY_CHECKS; 查询当前外键约束是否打开 ; 设置为1的时候外键约束是打 ...

  8. MySQL中删除数据的两种方法

    转自:http://blog.csdn.net/apache6/article/details/2778878 1. 在MySQL中有两种方法可以删除数据: 一种是delete语句,另一种是trunc ...

  9. 【MYSQL】删除数据后自动增长列归0的问题

    在清空数据表后发现自动增长id列在新增数据后仍然会按照之前的顺序生成 强迫症,就是想清空数据后让id从0开始,于是百度 执行以下sql语句可以让自动增长列归0 truncate table 表名 这是 ...

随机推荐

  1. Java的get、post请求

    URLConnection package com.shuzf.http; import java.io.BufferedReader; import java.io.IOException; imp ...

  2. Elastic Stack-Elasticsearch使用介绍(一)

    一.前言     Elasticsearch对外提供RESTful API,下面的演示我们主要使用Postman,进行一系列的Demo演示,这款工具方便各位前端大大或者对接口调试的神器: 安装过于简单 ...

  3. 第二部分之AOF持久化(第十一章)

    AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态的.被写入AOF文件的所有命令都是以Redis的命令请求协议格式(纯文本)保存的. 一,AOF持久化的实现 1.命令追加 当AOF持 ...

  4. 第三章· Redis消息队列

    一.生产消费模型 二.Redis发布消息的两种模式

  5. linux添加超级管理员用户,修改,删除用户

    useradd一个用户后,去修改/etc/passwd文件中的这个用户这一行,把其中的uid改为0,gid改为0(其中****代表一个用户名)这样****就具有root权限了 如:root2:x:0: ...

  6. SpringMvc的自动装箱和GET请求参数可以为自定义对象的思考

    在我的概念里边,GET请求需要加上注解@RequestParam,然后它的参数类型只能是 基本数据类型 或者 基本数据类型的包装类,比如:@RequestParam String name(默认是必传 ...

  7. 【JVM】关于类加载器准备阶段的一道面试题目

    一个经典的延伸问题 我们来看一个经典的延伸问题,准备阶段谈到静态变量,那么对于常量和不同静态变量有什么区别? 需要明确的是,没有人能够精确的理解和记忆所有信息,如果碰到这种问题,有直接答案当然最好:没 ...

  8. Win10修改编辑文件无法保存怎么办(没有权限)

    Win10修改编辑hosts文件无法保存怎么办 修改一些系统文件无法保存说明这个账户没有“写”这个权限 这里以hosts文件为例,为账户增加读写权限: 首先进入Win10系统的hosts文件所在位置 ...

  9. 导出python的环境

    1.导出 pip freeze >  packegas.txt 2.在其他环境安装 pip install -r  packages.txt

  10. 【原创】支持同时生成多个main函数 makefile 模板

    背景: 去年做项目的时候,由于有需要编译出多个可执行文件的需求,修改了Makefile使其支持生成多个结果(编译多个含有main函数的文件),但总觉得自己的实现不够完美. 今年又遇到这样需求的时候,可 ...