热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

echarts无数据时显示无数据_面试题|无索引如何删除亿级数据?

作者:杨奇龙标签:MySQL、无索引、删除亿级数据转自:yangyidba(yangyidba)一业务需求某业务表a数据量大约4.7亿&#

作者:杨奇龙

标签:MySQL、无索引、删除亿级数据

转自:yangyidba(yangyidba)

一 业务需求

某业务表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&#61;&#39;xxx&#39; and id >&#61;min_id and id <&#61;max_id

3 init_id &#61; max_id

代码如下:

def get_current_max_id():

"""

获取当前最大的id

:return:

"""

get_max_id &#61; """select max(a.id) max_id from a"""

try:

mydb &#61; pymysql.connect(

host&#61;IP,

port&#61;int(PORT),

user&#61;USER,

read_timeout&#61;5, write_timeout&#61;5,

charset&#61;&#39;utf8&#39;, autocommit&#61;True)

cursor &#61; mydb.cursor(pymysql.cursors.DictCursor)

cursor.execute(get_max_id)

data &#61; 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][&#39;max_id&#39;])

return data[0][&#39;max_id&#39;]

def get_min_max_id(min_id):

"""

:param min_id:

:return:

"""

get_ids &#61; """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&#61;min_id)

try:

mydb &#61; pymysql.connect(

host&#61;IP,

port&#61;int(PORT),

user&#61;USER,

read_timeout&#61;5, write_timeout&#61;5,

charset&#61;&#39;utf8&#39;, database&#61;&#39;test&#39;, autocommit&#61;True)

cursor &#61; mydb.cursor(pymysql.cursors.DictCursor)

cursor.execute(get_ids)

data &#61; cursor.fetchall()

except Exception as e:

print traceback.format_exc(e)

exit(0)

finally:

mydb.close()

return data[0][&#39;min_id&#39;], data[0][&#39;max_id&#39;]

def del_tokens(min_id, max_id):

"""

:param min_id:

:param max_id:

:return:

"""

del_token &#61; """delete from a

where client_id in (&#39;xxx&#39;,&#39;yyy&#39;) and id>&#61;%s and id<&#61;%s """

try:

mydb &#61; pymysql.connect(

host&#61;IP,

port&#61;int(PORT),

user&#61;USER,

read_timeout&#61;5, write_timeout&#61;5,

charset&#61;&#39;utf8&#39;, database&#61;&#39;test&#39;, autocommit&#61;True)

cursor &#61; mydb.cursor(pymysql.cursors.DictCursor)

rows &#61; 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&#61;file_name)

exit(-1)

with open(file_name, &#39;r&#39;) as fh:

del_id &#61; fh.readline().strip()

if not del_id.isdigit():

print "it is &#39;{delid}&#39;, not a num , exit ".format(delid&#61;del_id)

exit(-1)

return del_id

def main():

file_name &#61; &#39;/tmp/del_aid.id&#39;

rows_deleted &#61; 0

maxid &#61; get_current_max_id()

init_id &#61; get_last_del_id(file_name)

while True:

min_id, max_id &#61; get_min_max_id(init_id)

if max_id > maxid:

with open(&#39;/tmp/del_aid.id&#39;, &#39;w&#39;) as f:

f.write(str(min_id))

print "delete end at : {end_id}".format(end_id&#61;init_id)

exit(0)

rows &#61; del_tokens(int(min_id), int(max_id))

init_id &#61; max_id

rows_deleted &#43;&#61; rows

print "delete at %d ,and we have deleted %d rows " % (max_id, rows_deleted)

time.sleep(0.3) ### 可以控制每秒删除的速度

if __name__ &#61;&#61; &#39;__main__&#39;:

main()

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

2.3 如何更快速的删除

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

推荐文章

工具|Explain 使用分析

哪些因素会导致慢查询&#xff1f;

关于「3306π」社区

围绕 MySQL 核心技术&#xff0c;将互联网行业中最重要的数据化解决方案带到传统行业中&#xff1b;囊括其他开源技术Redis、MongoDB、Hbase、Hadoop、ElasticSearch、Storm、Spark等&#xff1b;分享干货知识&#xff0c;即便是赞助商&#xff0c;也要求如此&#xff0c;拒绝放水。

ca7a1193fe64797983c91f69c1a0914e.png




推荐阅读
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • WhenIusepythontoapplythepymysqlmoduletoaddafieldtoatableinthemysqldatabase,itdo ... [详细]
  • PDO MySQL
    PDOMySQL如果文章有成千上万篇,该怎样保存?数据保存有多种方式,比如单机文件、单机数据库(SQLite)、网络数据库(MySQL、MariaDB)等等。根据项目来选择,做We ... [详细]
  • MySQL语句大全:创建、授权、查询、修改等【MySQL】的使用方法详解
    本文详细介绍了MySQL语句的使用方法,包括创建用户、授权、查询、修改等操作。通过连接MySQL数据库,可以使用命令创建用户,并指定该用户在哪个主机上可以登录。同时,还可以设置用户的登录密码。通过本文,您可以全面了解MySQL语句的使用方法。 ... [详细]
  • 本文介绍了如何使用PHP代码将表格导出为UTF8格式的Excel文件。首先,需要连接到数据库并获取表格的列名。然后,设置文件名和文件指针,并将内容写入文件。最后,设置响应头部,将文件作为附件下载。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • React项目中运用React技巧解决实际问题的总结
    本文总结了在React项目中如何运用React技巧解决一些实际问题,包括取消请求和页面卸载的关联,利用useEffect和AbortController等技术实现请求的取消。文章中的代码是简化后的例子,但思想是相通的。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • Netty源代码分析服务器端启动ServerBootstrap初始化
    本文主要分析了Netty源代码中服务器端启动的过程,包括ServerBootstrap的初始化和相关参数的设置。通过分析NioEventLoopGroup、NioServerSocketChannel、ChannelOption.SO_BACKLOG等关键组件和选项的作用,深入理解Netty服务器端的启动过程。同时,还介绍了LoggingHandler的作用和使用方法,帮助读者更好地理解Netty源代码。 ... [详细]
  • 【爬虫】关于企业信用信息公示系统加速乐最新反爬虫机制
    ( ̄▽ ̄)~又得半夜修仙了,作为一个爬虫小白,花了3天时间写好的程序,才跑了一个月目标网站就更新了,是有点悲催,还是要只有一天的时间重构。升级后网站的层次结构并没有太多变化,表面上 ... [详细]
  • python+selenium十:基于原生selenium的二次封装fromseleniumimportwebdriverfromselenium.webdriv ... [详细]
  • PHP操作MySql数据库_PHP教程:链接数据库$conn@mysql_connect(localhost,root,88888888)ordie(链接错误);解决中文乱码mys ... [详细]
author-avatar
i1L3i1L4
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有