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分块读取大数据,避免内存不足
随机推荐
- 使用DataV制作的一个数据报表
之前接到一个做数据报表的需求,当时准备使用echarts自己画.后来考虑时间来不及,着急要,再加上一直在使用阿里云的产品,就在阿里云上个找了找数据大屏的服务.于是很快做出了一款. 然后看到 https ...
- 一些常见的http状态码
HTTP状态码是服务器和客户端之间交流信息的语言,下面列出一些常见的HTTP状态码. 1XX系列 指定客户端应相应的某些动作,代表请求已被接受,需要继续处理.由于在HTTP/1.0协议中没有定义任何1 ...
- DataGridView中的rows.Count比实际行数多1的原因以及解决办法
场景 DataGridView怎样实现添加.删除.上移.下移一行: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10281414 ...
- Typescript基础(3)——类
前言 今天继续typescript的学习,开始ts类的学习. 类 类的实现 在ES6中新增了类的概念.我们先看ES6中类的实现. class Person { constructor(name,age ...
- Java --Lamda表达式
Lamda:属于函数式编程的概念: interface IMessage { public void print() ; } public class TestDemo { public static ...
- iOS 国际本地化(对新项目集成和已有项目集成)
第一推荐一篇金先生的博客,受益非浅,在这里真诚的感谢 https://www.jianshu.com/p/7cb0fad6d06f金小白 首先金小白先生把两种方式都做了介绍,第一种我就不在过多详细的讲 ...
- Xcode修改工程文件名字
http://stackoverflow.com/questions/8262613/renaming-xcode-4-project-and-the-actual-folder
- 在MVC视图中将数字转换为string类型后保留两位小数
<td>@item.recharge_reward_rate.ToString("F2")%</td> @*保留小数两位*@ <td>@item ...
- Lnmp架构部署动态网站环境.2019-7-3-1.2
Nginx安装 一.安装准备 Pcre(Perl Compatible Regular Expressions,兼容正则表达式)安装pcre库是为了使Nginx支持HTTP Rewrite模块. 安装 ...
- Shell命令-系统信息及显示之df、top
文件及内容处理 - df.top 1. df:报告文件系统磁盘空间的使用情况 df命令的功能说明 df 命令用于显示目前在Linux系统上的文件系统的磁盘使用情况统计. df命令的语法格式 df [O ...