今天接到一位开发同学的数据操作需求,需求看似很简单,需要执行下面的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. python小白——进阶之路——day2天-———变量的缓存机制+自动类型转换

    # ###同一文件,变量的缓存机制 ''' -->Number 部分 1.对于整型而言,-5~正无穷范围内的相同值 id一致 2.对于浮点数而言,非负数范围内的相同值 id一致 3.布尔值而言, ...

  2. (转)lwip TCP client & FreeRTOS 打开TCP 的 保活机制 LWIP_TCP_KEEPALIVE==1

    参考大神教程:http://blog.sina.com.cn/s/blog_62a85b950101aw8x.html   老衲五木 :http://blog.sina.com.cn/s/blog_6 ...

  3. PTA 天梯赛练习 7-11 玩转二叉树-二叉树重建

    以前就思考过这个问题,但是没有深入的想过,这是一种叫二叉树重建的典型题目 如果给出中序和前序,求出后序遍历. 这道题则求的是交换儿子节点的层序遍历. 二叉树的重建应该怎么重建,首先我们知道,先根遍历, ...

  4. [Alpha阶段]第六次Scrum Meeting

    Scrum Meeting博客目录 [Alpha阶段]第六次Scrum Meeting 基本信息 名称 时间 地点 时长 第六次Scrum Meeting 19/04/10 教2 1层 50min 相 ...

  5. Python 中关于 round 函数的坑

    round函数很简单(而且不需要引入math模块),对浮点数进行近似取值,保留几位小数. 比如 # -*- coding: UTF-8 -*- r1=round(12.12345,3) r2=roun ...

  6. nginx代理部署Vue与React项目

    nginx代理部署Vue与React项目 一,介绍与需求 1.1,介绍 Nginx (engine x) 是一个高性能的HTTP和反向代理服务,也是一个IMAP/POP3/SMTP服务.Nginx是由 ...

  7. Python——三级菜单

    #三级菜单函数 menu = { '北京':{ 海淀:{ '五道口':{} '中关村':{} '上帝':{} } '昌平':{} '朝阳':{} '东城':{} }, '上海':{} '山东':{} ...

  8. springboot jpa 复合主键

    https://blog.csdn.net/wyc_cs/article/details/9031991 创建一个复合主键类 public class LevelPostMultiKeysClass ...

  9. 7.docker日志收集

    默认情况下,docker logs或者docker service logs显示命令的输出,就像在终端中以交互方式运行命令时一样.UNIX和Linux命令通常开在运行时间上三个I / O流,所谓的 S ...

  10. P2495 [SDOI2011]消耗战 lca倍增+虚树+树形dp

    题目:给出n个点的树  q次询问  问切断 k个点(不和1号点联通)的最小代价是多少 思路:树形dp  sum[i]表示切断i的子树中需要切断的点的最小代价是多少 mi[i]表示1--i中的最小边权 ...