解决python存数据库速度太慢的问题


Posted in Python onApril 23, 2021

在项目中遇到一个问题,需要从文本中读取三万条数据写入mysql数据库,文件中为用@分割的sql语句,但是在读取的过程中发现速度过慢,三万八千条数据需要220秒,问题代码片段如下:

def read_to_mysql(filecata, targetDir):
 '''
 用来写入数据库,写入后会剪贴掉文件
 filecata 为保存有文件地址的list,已去掉尾部的空格
 :param filecata: 文件目录
 :param targetDir: 要复制的目标目录
 :return:
 '''
 root_dir = os.path.abspath(os.path.join(os.getcwd(), "./"))
 config = configparser.ConfigParser()
 config.read(root_dir + "/config.ini")
 __host = config.get("DatabaseOfWRT", "host")
 __database_name = config.get("DatabaseOfWRT", "database")
 __user_name = config.get("DatabaseOfWRT", "username")
 __user_passwaord = config.get("DatabaseOfWRT", "password")
 __charset = config.get("DatabaseOfWRT", "charset")
 conn = pymysql.connect(
  host=__host,
  user=__user_name, password=__user_passwaord,
  database=__database_name,
  charset=__charset
 )
 cursor = conn.cursor()
 with open(filecata, "r", encoding='utf-8') as f:
  data = f.read() # 读取文件
  data_list = data.split('@')
  del data_list[-1]
  starttime = int(time.time())
  for data_str in data_list:
   data_str = str(data_str)
   sql = data_str + ';'
   cursor.execute(sql)
   conn.commit()
   print(flag)
 copy_del_file(filecata, targetDir) # 用来剪切的函数,此处不影响,因而省略
 cursor.close()
 conn.close()

经测试发现,影响速度的主要原因是commit(),因为没过几秒提交一次即可,但是因为提交的字符长度有限制,所以要设置一个合理的时间读取,代码修改如下:

def read_to_mysql(filecata, targetDir):
 '''
 用来写入数据库,写入后会剪贴掉文件
 filecata 为保存有文件地址的list,已去掉尾部的空格
 :param filecata:
 :param targetDir: 要复制的目标目录
 :return:
 '''
 root_dir = os.path.abspath(os.path.join(os.getcwd(), "./"))
 config = configparser.ConfigParser()
 config.read(root_dir + "/config.ini")
 __host = config.get("DatabaseOfWRT", "host")
 __database_name = config.get("DatabaseOfWRT", "database")
 __user_name = config.get("DatabaseOfWRT", "username")
 __user_passwaord = config.get("DatabaseOfWRT", "password")
 __charset = config.get("DatabaseOfWRT", "charset")
 conn = pymysql.connect(
  host=__host,
  user=__user_name, password=__user_passwaord,
  database=__database_name,
  charset=__charset
 )
 cursor = conn.cursor()
 with open(filecata, "r", encoding='utf-8') as f:
  data = f.read() # 读取文件
  data_list = data.split('@')
  del data_list[-1]
  starttime = int(time.time())
  for data_str in data_list:
   endtime = int(time.time())
   data_str = str(data_str)
   sql = data_str + ';'
   cursor.execute(sql)
   if endtime - starttime ==10: # 每过十秒提交一次
    starttime = int(time.time())
    conn.commit()
 conn.commit()
 copy_del_file(filecata, targetDir)
 cursor.close()
 conn.close()
 return flag

此时写入三万八千条数据需要9秒

补充:python 连数据库cursur.fetchall ()速度慢的解决方案

解决游标遍历慢的方法:

一行一行去遍历,而不是一下全部读取出来

将cursur.fetchall()更改为for i in cursur:

补充:python 读取文件时速度的问题

"""举例 读取文件"""
# 第一种方式
with open('test.txt', 'r', encoding='utf-8') as f:
 info = f.readlines()
 for line in info:
 pass
# 第二种方式
with open('test.txt', 'r', encoding='utf-8') as f:
 for line in f:
 pass

对于以上两种方式读取文件,各自有各自的用途,当用两种方式都可以时,第二种方式的效率是第一种的几个量级, readlines()将文件内容读取到内存的list中,操作虽然方便,但是消耗内存,运行效率慢。

原生的f是将文件内容读到生成器中, 当需要操作时,从生成器中循环出来,速度很快,操作大文件时建议用第二种方式!

Python 相关文章推荐
通过mod_python配置运行在Apache上的Django框架
Jul 22 Python
Python中定时任务框架APScheduler的快速入门指南
Jul 06 Python
Python实现读取机器硬件信息的方法示例
Jun 09 Python
opencv与numpy的图像基本操作
Mar 08 Python
python实现微信自动回复机器人功能
Jul 11 Python
Python loguru日志库之高效输出控制台日志和日志记录
Mar 07 Python
如何理解python中数字列表
May 29 Python
keras使用Sequence类调用大规模数据集进行训练的实现
Jun 22 Python
如何在python中判断变量的类型
Jul 29 Python
Python selenium爬取微信公众号文章代码详解
Aug 12 Python
python 如何将office文件转换为PDF
Sep 22 Python
python绕过图片滑动验证码实现爬取PTA所有题目功能 附源码
Jan 06 Python
python实战之90行代码写个猜数字游戏
Apr 22 #Python
python实战之一步一步教你绘制小猪佩奇
Apr 22 #Python
python 破解加密zip文件的密码
python入门之算法学习
Apr 22 #Python
python使用XPath解析数据爬取起点小说网数据
Apr 22 #Python
python 实现德洛内三角剖分的操作
python 三边测量定位的实现代码
You might like
PHP获取当前文件所在目录 getcwd()函数
2009/05/13 PHP
PHP 类商品秒杀计时实现代码
2010/05/05 PHP
php中取得URL的根域名的代码
2011/03/23 PHP
Web程序工作原理详解
2014/12/25 PHP
php打造智能化的柱状图程序,用于报表等
2015/06/19 PHP
WordPress主题制作中自定义头部的相关PHP函数解析
2016/01/08 PHP
js字符编码函数区别分析
2008/06/05 Javascript
jQuery Ajax提交表单查询获得数据实例代码
2012/09/19 Javascript
JavaScript中for..in循环陷阱介绍
2013/11/12 Javascript
javascript动态向网页中添加表格实现代码
2014/02/19 Javascript
原生js仿jq判断当前浏览器是否为ie,精确到ie6~8
2014/08/30 Javascript
DOM基础教程之使用DOM + Css
2015/01/20 Javascript
JavaScript简介
2015/02/15 Javascript
javascript实现数组中的内容随机输出
2015/08/11 Javascript
JavaScript+CSS无限极分类效果完整实现方法
2015/12/22 Javascript
jquery基于layui实现二级联动下拉选择(省份城市选择)
2017/06/20 jQuery
es6 字符串String的扩展(实例讲解)
2017/08/03 Javascript
layui.js实现的表单验证功能示例
2017/11/15 Javascript
NW.js 简介与使用方法
2018/02/01 Javascript
解决Layui中layer报错的问题
2019/09/03 Javascript
基于JS实现父组件的请求服务过程解析
2019/10/14 Javascript
Vue两种组件类型:递归组件和动态组件的用法
2020/08/06 Javascript
vue3.0自定义指令(drectives)知识点总结
2020/12/27 Vue.js
Python使用turtule画五角星的方法
2015/07/09 Python
详解Python装饰器由浅入深
2016/12/09 Python
python 获取文件下所有文件或目录os.walk()的实例
2018/04/23 Python
python opencv根据颜色进行目标检测的方法示例
2020/01/15 Python
python 利用matplotlib在3D空间绘制二次抛物面的案例
2021/02/06 Python
sealed修饰符是干什么的
2012/10/23 面试题
软件测试常见笔试题
2012/02/04 面试题
毕业生求职简历的自我评价
2013/10/23 职场文书
2014领导干部四风问题查摆思想汇报
2014/09/13 职场文书
思想品德评语大全
2014/12/31 职场文书
学雷锋日活动总结
2015/02/06 职场文书
无保留意见审计报告
2015/06/05 职场文书
解决MySQL添加新用户-ERROR 1045 (28000)的问题
2022/03/03 MySQL