点击蓝色“程序猿DD”关注我哟

加个“星标”,不忘签到哦

来源:yangyidba


关注我,回复口令获取可获取独家整理的学习资料:

001:领取《Spring Boot基础教程》

002:领取《Spring Cloud基础教程》

- 003:领取《Java开发规范1.5》(最新版)

一、业务需求

某业务表a 数据量大约4.7亿,单表物理大小为370G,其中某些指定xxid='xxx'值的记录大约2亿。受限于磁盘空间比较紧张,需要对在无索引的情况下删除无效数据。如何优雅的删除呢?

二、思路

2.1 xxid本身有索引

存在索引的情况下就比较简单,直接利用索引进行删除,写一个for 循环语句 每次删除500行,每次判断delete 影响的行数可以累加计算删除了多少行,直到删除结果为0行。

delete from a where xxid='xxx' limit 500 ;

那么问题来了 ,如果要求不能创建索引怎么处理?

2.2 xxid 字段无索引

因为表占用的空间已经比较大 370G ,再添加索引会更大。因为没有索引,故我们不能直接像方法一 那样 根据 where xxxid='xxx' 删除数据,那样更慢,可能会引发故障。

我们采取分而治之的方式,基于主键把表的数据分段,比如每段1000行-2000行(如果主键id不连续 则实际数据量会小于指定分段数据)。然后在这1000行里面删除指定的数据,这样delete的执行效率会比直接依赖 xxxid='xxx' 好很多。

1 select min(a.id) min_id,max(a.id) max_id
from (select id from a where id>{init_id} order by id limit 1000) a
2 delete from a where xxid='xxx' and id >=min_id and id <=max_id
3 init_id = max_id

代码如下:

def get_current_max_id():    """  获取当前最大的id   :return:    """  get_max_id = """select max(a.id) max_id from a"""    try:    mydb = pymysql.connect(    host=IP,   port=int(PORT),    user=USER, read_timeout=5, write_timeout=5,  charset='utf8',  autocommit=True)   cursor = mydb.cursor(pymysql.cursors.DictCursor)   cursor.execute(get_max_id)  data = cursor.fetchall()   except Exception as e:  print traceback.format_exc(e)   exit(0) finally:    mydb.close()    print "we get max id of table : %s" % (data[0]['max_id'])   return data[0]['max_id']
def get_min_max_id(min_id): """  :param min_id:  :return:    """  get_ids = """select min(a.id) min_id,max(a.id) max_id from  (select id from a where id>{init_id} order by id limit 2000) a
""".format(init_id=min_id)  try:    mydb = pymysql.connect(    host=IP,   port=int(PORT),    user=USER, read_timeout=5, write_timeout=5,  charset='utf8', database='test', autocommit=True)    cursor = mydb.cursor(pymysql.cursors.DictCursor)   cursor.execute(get_ids) data = cursor.fetchall()   except Exception as e:  print traceback.format_exc(e)   exit(0) finally:    mydb.close()    return data[0]['min_id'], data[0]['max_id']
def del_tokens(min_id, max_id): """  :param min_id:  :param max_id:  :return:    """  del_token = """delete from a    where client_id in ('xxx','yyy') and id>=%s and id<=%s """   try:    mydb = pymysql.connect(    host=IP,   port=int(PORT),    user=USER, read_timeout=5, write_timeout=5,  charset='utf8', database='test', autocommit=True)    cursor = mydb.cursor(pymysql.cursors.DictCursor)   rows = cursor.execute(del_token, (min_id, max_id)) except Exception as e:  print traceback.format_exc(e)   exit(0) finally:    mydb.close()    return rows
def get_last_del_id(file_name): if not os.path.exists(file_name):   print "{file} is not exist ,exit .".format(file=file_name)   exit(-1)    with open(file_name, 'r') as fh:  del_id = fh.readline().strip() if not del_id.isdigit():    print "it is '{delid}', not a num , exit ".format(delid=del_id)    exit(-1)    return del_id
def main(): file_name = '/tmp/del_aid.id'    rows_deleted = 0   maxid = get_current_max_id()   init_id = get_last_del_id(file_name)   while True: min_id, max_id = get_min_max_id(init_id)   if max_id > maxid:   with open('/tmp/del_aid.id', 'w') as f: f.write(str(min_id))    print "delete end at : {end_id}".format(end_id=init_id)  exit(0) rows = del_tokens(int(min_id), int(max_id))    init_id = max_id   rows_deleted += rows  print "delete at  %d ,and we have  deleted %d  rows " % (max_id, rows_deleted)    time.sleep(0.3)  ### 可以控制每秒删除的速度
if __name__ == '__main__':  main()

这个脚本可以记录上一次的id,用上一次id 作为 init_id进行删除。第一次使用的时候需要手工初始化/tmp/del_aid.id 比如写入 0 或者符合条件的最小主键 id。

2.3 如何更快速的删除

这个环节就当做思考题吧,可以不考虑从库的延迟。大家有什么好的思路,可以分享一下。

推荐关注

本文作者的个人公众号,长期关注于数据库技术以及性能优化,故障案例分析,数据库运维技术知识分享,个人成长和自我管理等主题,欢迎扫码关注。


推荐阅读

  • 再见微服务,从100多个问题儿童到一个超级明星

  • JDK 13 的五大新特性!你最中意哪个?

  • MySQL百万级数据分页查询及优化

  • 这个注解一次搞定限流与熔断降级

  • 阿里云新版主页,我还以为打开了淘宝..


活动介绍:自律到极致-人生才精致:第9期

活动奖励:

  • 一等奖:天猫精灵 * 1

  • 二等奖:我的星球会员 * 5

扫描下面二维码签到参与

关注我,加个星标,不忘签到哦~

2019

与大家聊聊技术人的斜杠生活

点一点“阅读原文”小惊喜在等你

无索引的亿级数据该如何删除?相关推荐

  1. MySQL表上亿级数据量实现删除重复记录

    上周从数据采集部门拿到一批400份的json文件,每个文件里30w+的json对象,对象里有uid,对重复的uid,需要去重下. 电脑配置4核8G 废话不多说,直接上干货. 1.创建表datatest ...

  2. mysql没有索引删除一亿数据_mysql数据库如何实现亿级数据快速清理

    今天收到磁盘报警异常,50G的磁盘被撑爆了,分析解决过程如下: 1. 进入linux服务器,查看mysql文件夹中各个数据库所占的磁盘空间大小 看到了吗,光olderdb就占了25G 2. 用SQLy ...

  3. 亿级流量系统架构之如何支撑百亿级数据的存储与计算【转载 石杉的架构笔记】-1...

    亿级流量系统架构之如何支撑百亿级数据的存储与计算[石杉的架构笔记] 原创: 中华石杉 "本文聊一下笔者几年前所带的团队负责的多个项目中的其中一个,用这个项目来聊聊一个亿级流量系统架构演进的过 ...

  4. MySQL 亿级数据的迁移、清洗、与审计分析

    职业生涯中,曾经有两年多时间从事IT内部审计的工作,需要介入公司大部分的业务系统,主要的数据库为 MySQL,特别是三年期审计,需要统计三年的数据素材(亿级以上).对MySQL的性能有一些自已的理解, ...

  5. 唯品会翻牌ClickHouse后,实现百亿级数据自助分析

    本文根据王玉老师在[deeplus直播第266期]线上分享演讲内容整理而成.(文末有获取本期PPT&回放的方式,不要错过) 王玉 唯品会实时平台OLAP团队负责人 负责唯品会Presto.Cl ...

  6. pymongo 亿级数据查询技术总结之一

    文章目录 序言 亿级数据下find的性能 count 的测试结果 数据库优化首要策略: 加索引就好? 序言 这么多年来做过好几个使用mongodb的项目, 这里主要记录下大数据使用上的一些技巧和要点. ...

  7. 10亿级数据规模的半监督图像分类模型,Imagenet测试精度高达81.2% | 技术头条...

    译者 | linstancy 作者| I. Zeki Yanlniz, Herve Jegou, Kan Chen, Manohar Paluri, Dhruv Mahajan 编辑 | 蓝色琥珀鱼, ...

  8. Redis亿级数据过滤和布隆过滤器

    来自:我没有三颗心脏 一.布隆过滤器简介 上一次 我们学会了使用 HyperLogLog 来对大数据进行一个估算,它非常有价值,可以解决很多精确度不高的统计需求.但是如果我们想知道某一个值是不是已经在 ...

  9. mysql数据清洗_mysql数据库如何实现亿级数据快速清理

    今天收到磁盘报警异常,50G的磁盘被撑爆了,分析解决过程如下: 1. 进入linux服务器,查看mysql文件夹中各个数据库所占的磁盘空间大小 看到了吗,光olderdb就占了25G 2. 用SQLy ...

最新文章

  1. Linux下使用nmap扫描局域网存活的IP
  2. AndroidStudio直接通过gradle无mk编译生成so
  3. vscode 新建cpp文件_Visual Studio Code (vscode)编译C++
  4. centos mysql 5.5 art_Linux CentOS6.5下编译安装MySQL 5.5.51''''
  5. 超级网管员系列图书介绍
  6. C++独立游戏存档模块设计 VERSION_1.7
  7. 小米笔记本PRO黑苹果使用第三方蓝牙设备
  8. SHP格式数据点线面无边界坐标生成经纬度边界点集合数据
  9. 小学认识计算机说课ppt,“认识计算机”说课稿.ppt
  10. mysql execute stmt_[转载]MySql 数据库--stmt语句
  11. docsify操作和Docker部署流程文档
  12. 为什么我说,卖货直播平台开发的定位可以从这方面入手
  13. Java spring boot 实现支付宝支付
  14. linux个人学习记录
  15. 情人节送什么礼物?四款情人节潮流数码好物推荐
  16. 低功耗蓝牙搜索广播的实现流流程介绍 /BLE scan flow ----- 蓝牙低功耗协议栈
  17. C# DirectoryInfo GetFiles()获得的文件列表与本机下文件顺序一致
  18. 【cocos shader 004】 聚光灯 灯光 烘焙 效果
  19. 软件模块化定制将造成传统软件消失?
  20. JS安全防护算法与逆向分析——新浪微博登录JS加密算法

热门文章

  1. php serialize unserialize 数据序列化 与 反序列化
  2. python flask gunicorn nginx 部署
  3. linux 内核可装载模块 版本检查机制
  4. Android--GridView实现动态文字排版
  5. linux笔记本不关机直接合上,笔记本电脑不关机直接合上行吗
  6. linux正则表达式的使用方法,Linux中基本正则表达式
  7. antd 函数组件_react函数组件中引用antd<Form/>组件demo
  8. linux磁盘管理相关命令,Linux | 磁盘管理命令
  9. linux打理ftp用户,Linux中如何添加/删除FTP用户并设置权限
  10. php访问nfs目录,PHP NFS的实现代码