pymysql 读取大数据内存卡死的解决方案
背景:目前表中只有5G(后期持续增长),但是其中一个字段(以下称为detail字段)存了2M(不一定2M,部分为0,平均下来就是2M),字段中存的是一个数组,数组中存N个json数据。这个字段如下:
[{"A": "A", "B": "B", "C": "C", "D": "D"}...]
要是拆表的话,可能要拆好多个,要是存多行根据阿里巴巴《Java 开发手册》提出单表行数超过 500 万行,也不是很建议。希望有大佬能指教一下。
回到正题,一开始是分两个表存储,一个表存基本信息(A表),一个表(B表)存关联字段,及detail字段。貌似没有啥用,按需求现要将两张表合在一起供BI去处理。直接复制了那张基础字段的A表,通过遍历B表根据关联字段进行更新。但是在select的时候内存读入的数据太大直接卡死(狗头)。于是在网上查找如何通过pymysql处理大数据的问题。解决方案如下:
1.通过limit分批次读取数据进行操作:
import pymysql
up_db = pymysql.connections.Connection(host=MYSQL_HOST,
port=MYSQL_PORT,
user=MYSQL_USER,
password=MYSQL_PASSWORD,
db=MYSQL_DB,
charset='utf8mb4',)
count = 0
while True:
# if count == 2:
# break
select_sql = "select sec_report_id,detail from sec_report_original_data_detail limit %s,2"%(count)
up_cursor = up_db.cursor()
up_cursor.execute(select_sql)
result = up_cursor.fetchall()
for data in result:
sec_report_id = data[0]
detail = data[1]
update_sql = "update `sec_report_original_data_intact` set detail = '%s' where `sec_report_id` = '%s' " % (
db.escape_string(detail), sec_report_id)
print(update_sql)
res = up_cursor.execute(update_sql)
if res:
print(res)
up_db.commit()
print(f'{sec_report_id}插入成功')
count+=2
可以解决问题,不过只是拿了几条做测试(我用的是第二种),这里没写终止条件,有朋友要用的话自己加上。
2.通过pymysql的SSCursor没有缓存的游标
pymysql.cursors.SSCursor代替默认的cursor会从数据库中一条一条的读取记录,从而不会造成内存卡死,但是也有需要注意的地方:
- 这个游标对象只能读完所有行之后才能处理其他sql。如果你需要并行执行sql,需要重新生成一个连接
- 必须一次性读完所有行,每次读取后处理数据要快,不能超过60s,否则mysql将会断开这次连接(没有遇到这个问题,遇到的可以讨论一下)
import pymysql
db = pymysql.connections.Connection(host=MYSQL_HOST,
port=MYSQL_PORT,
user=MYSQL_USER,
password=MYSQL_PASSWORD,
db=MYSQL_DB,
charset='utf8mb4',
cursorclass=pymysql.cursors.SSDictCursor)
up_db = pymysql.connections.Connection(host=MYSQL_HOST,
port=MYSQL_PORT,
user=MYSQL_USER,
password=MYSQL_PASSWORD,
db=MYSQL_DB,
charset='utf8mb4',)
up_cursor = up_db.cursor()
cursor = pymysql.cursors.SSCursor(db)
select_sql = "select sec_report_id,detail from sec_report_original_data_detail"
cursor.execute(select_sql)
result = cursor.fetchone()
try:
while result is not None:
sec_report_id = result[0]
detail = result[1]
update_sql = "update `sec_report_original_data_intact` set detail = '%s' where `sec_report_id` = '%s'"%(db.escape_string(detail),sec_report_id)
res = up_cursor.execute(update_sql)
if res:
print(res)
up_db.commit()
print(f'{sec_report_id}插入成功')
result = cursor.fetchone()
except Exception as e:
print(e)
finally:
up_cursor.close()
cursor.close()
db.close()
解决了一次性读取大数据的方法,但是没找到特别好的存储那个
detail字段中数据的办法,有朋友了解的可以沟通一下。
pymysql 读取大数据内存卡死的解决方案的更多相关文章
- CRL快速开发框架系列教程十一(大数据分库分表解决方案)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- JAVA 大数据内存耗用测试
JAVA 大数据内存耗用测试import java.lang.management.ManagementFactory;import java.lang.management.MemoryMXBean ...
- ASP.NET MVC + EF 利用存储过程读取大数据,1亿数据测试很OK
看到本文的标题,相信你会忍不住进来看看! 没错,本文要讲的就是这个重量级的东西,这个不仅仅支持单表查询,更能支持连接查询, 加入一个表10W数据,另一个表也是10万数据,当你用linq建立一个连接查询 ...
- ASP.NET MVC + EF 利用存储过程读取大数据
ASP.NET MVC + EF 利用存储过程读取大数据,1亿数据测试很OK 看到本文的标题,相信你会忍不住进来看看! 没错,本文要讲的就是这个重量级的东西,这个不仅仅支持单表查询,更能支持连接查询, ...
- [C#]_[使用微软OpenXmlSDK (OpenXmlReader)读取xlsx表格] 读取大数据量100万条数据Excel文件解决方案
1.OpenXmlSDK是个很好的类库,可惜只能通过C#调用,C#的童鞋又福气了. 2.服务端程序由于没法安装office,所以这个对asp.net网站来说是最理想的库了.需要.net 4.0版本 ...
- DB2大数据量优化查询解决方案
利用DB2表分区的功能对大数据量的表进行分区,可以优化查询. 表分区介绍: 表分区是一种数据组织方案,它根据一列或多列中的值把表数据划分为多个称为数据分区 的存储对象. (我觉得表分区就类似于Wind ...
- Apache Kylin - 大数据下的OLAP解决方案
OLAPCube是一种典型的多维数据分析技术,Cube本身可以认为是不同维度数据组成的dataset,一个OLAP Cube 可以拥有多个维度(Dimension),以及多个事实(Factor Mea ...
- 基于TI 多核DSP 的大数据智能计算处理解决方案
北京太速科技有限公司 大数据智能计算,是未来的一个发展趋势,大数据计算系统主要完成数据的存储和管理:数据的检索与智能计算. 特别是在智能城市领域,由于人口聚集给城市带来了交通.医疗.建筑等各方面的压力 ...
- python分块读取大数据,避免内存不足
随机推荐
- SpringBoot系列之profles配置多环境(篇二)
SpringBoot系列之profles配置多环境(篇二) 继续上篇博客SpringBoot系列之profles配置多环境(篇一)之后,继续写一篇博客进行补充 写Spring项目时,在测试环境是一套数 ...
- 关于powermock报错org.powermock.reflect.exceptions.FieldNotFoundException: Field 'fTestClass' was not found in class org.junit.internal.runners.MethodValidator.问题解决
事件背景 使用PowerMock模拟一个局部变量,添加@RunWith(PowerMockRunner.class).@PrepareForTest(StudentService.class)注解成功 ...
- 多线程通信的两种方式? (可重入锁ReentrantLock和Object)
(一)Java中线程协作的最常见的两种方式: (1)利用Object的wait().notify()和notifyAll()方法及synchronized (2)使用Condition.Reentra ...
- ansible命令参数介绍
-m:要执行的模块,默认为command -a:模块的参数 -u:ssh连接的用户名,默认用root,ansible.cfg中可以配置 -k:提示输入ssh登录密码.当使用密码验证的时候用 -s:su ...
- Serlvet、JSP和JSTL的联系
没有无缘无故的爱和恨,没有无缘无故的编程 前言: 想这世间,没有无缘无故的爱,也没有无缘无故的恨,一切都有有原因的,我想编程亦是如此,技术时常更新,程序员时常学习,随着时间的推移,程序员发际线的增高, ...
- Python打包成exe文件很难?一分钟即可学会,并添加图标!
环境1.python 3.72.pyinstaller下载方式:2.1 python安装(略)2.2 安装pyinstaller打开DOS窗口输入以下命令:pip install pyinstalle ...
- 上传App Store 被拒问题及解决方案总结
最近公司比较忙,一直忙着写代码做新的应用,一连上线了几个应用,我们也是忙得焦头烂额的,都没时间做总结,今天趁APP审核期间,总结一下近期上传App Store遇到的一些问题和解决方法,以便以后查阅. ...
- 关于 Android 状态栏的适配总结
1.要求状态栏透明,我们的内容布局延伸到系统状态栏,就是人们口中说的沉浸式状态栏: Android 5.0 及其以后版本:设置属性 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCR ...
- 版本管理·玩转git(日志查看与版本切换)
如果你想更清晰地学习git,你必须要了解3个重要区域. 工作区:即开发者的工作目录 暂存区:修改已被记录,但尚未录入版本库的区域 版本库:存储变化日志及版本信息 当你在工作区进行开发工作时,git会记 ...
- 2_Swift基本数据类型
数字和基本数据类型 模型数据与数字,布尔值和其他基本类型. 逻辑值 struct Bool 一个值类型实例, 取值true或者flase Bool表示Swift中的布尔值.Bool通过使用其中一个布尔 ...