python测试mysql写入性能完整实例


Posted in Python onJanuary 18, 2018

本文主要研究的是python测试mysql写入性能,分享了一则完整代码,具体介绍如下。

测试环境:

(1) 阿里云服务器centos 6.5

(2) 2G内存

(3) 普通硬盘

(4) mysql 5.1.73 数据库存储引擎为 InnoDB

(5) python 2.7

(6) 客户端模块 mysql.connector

测试方法:

(1) 普通写入

(2) 批量写入

(3) 事务加批量写入

普通写入:

def ordinary_insert(count): 
  sql = "insert into stu(name,age,class)values('test mysql insert',30,8)" 
  for i in range(count): 
    cur.execute(sql)

批量写入,每次批量写入20条数据

def many_insert(count): 
  sql = "insert into stu(name,age,class)values(%s,%s,%s)" 
 
  loop = count/20 
  stus = (('test mysql insert', 30, 30), ('test mysql insert', 30, 31), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32) 
         ,('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), 
         ('test mysql insert', 30, 32), ('test mysql insert', 30, 32) 
        ,('test mysql insert', 30, 30), ('test mysql insert', 30, 31), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32) 
         ,('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), 
         ('test mysql insert', 30, 32), ('test mysql insert', 30, 32)) 
  #并不是元组里的数据越多越好 
  for i in range(loop): 
    cur.executemany(sql, stus)

事务加批量写入,每次批量写入20条数据,每20个批量写入作为一次事务提交

def transaction_insert(count): 
  sql = "insert into stu(name,age,class)values(%s,%s,%s)" 
  insert_lst = [] 
  loop = count/20 
 
  stus = (('test mysql insert', 30, 30), ('test mysql insert', 30, 31), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32) 
         ,('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), 
         ('test mysql insert', 30, 32), ('test mysql insert', 30, 32) 
        ,('test mysql insert', 30, 30), ('test mysql insert', 30, 31), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32) 
         ,('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), 
         ('test mysql insert', 30, 32), ('test mysql insert', 30, 32)) 
  #并不是元组里的数据越多越好 
  for i in range(loop): 
    insert_lst.append((sql,stus)) 
    if len(insert_lst) == 20: 
      conn.start_transaction() 
      for item in insert_lst: 
        cur.executemany(item[0], item[1]) 
      conn.commit() 
      print '0k' 
      insert_lst = [] 
 
  if len(insert_lst) > 0: 
    conn.start_transaction() 
    for item in insert_lst: 
      cur.executemany(item[0], item[1]) 
    conn.commit()

实验结果如下

数量  普通写入   many写入  事务加many写入 
1万  26.7s  1.7s    0.5s 
10万  266s   19s    5s 
100万 2553s   165s    49s

批量写入,相比于普通的多次写入,减少了网络传输次数,因而写入速度加快。

不论是单次写入还是批量写入,数据库内部都要开启一个事务以保证写入动作的完整,如果在应用层,我们自己开启事物,那么就可以避免每一次写入数据库自己都开启事务的开销,从而提升写入速度。

事务加批量写入速度大概是批量写入速度的3倍,是普通写入的50倍。

完整的测试代码如下:

#coding=utf-8 
''''' 
采用三种方法测试mysql.connector对mysql的写入性能,其他的例如mysqldb和pymysql客户端库的写入性能应该和mysql.connector一致 
采用批量写入时,由于减少了网络传输的次数因而速度加快 
开启事务,多次写入后再提交事务,其写入速度也会显著提升,这是由于单次的insert,数据库内部也会开启事务以保证一次写入的完整性 
如果开启事务,在事务内执行多次写入操作,那么就避免了每一次写入都开启事务,因而也会节省时间 
从测试效果来看,事务加批量写入的速度大概是批量写入的3倍,是普通写入的50倍 
数量  普通写入   many写入  事务加many写入 
1万  26.7s  1.7s    0.5s 
10万  266s   19s    5s 
100万 2553s   165s    49s 
 
将autocommit设置为true,执行insert时会直接写入数据库,否则在execute 插入命令时,默认开启事物,必须在最后commit,这样操作实际上减慢插入速度 
此外还需要注意的是mysql的数据库存储引擎如果是MyISAM,那么是不支持事务的,InnoDB 则支持事务 
''' 
import time 
import sys 
import mysql.connector 
reload(sys) 
sys.setdefaultencoding('utf-8') 
 
config = { 
    'host': '127.0.0.1', 
    'port': 3306, 
    'database': 'testsql', 
    'user': 'root', 
    'password': 'sheng', 
    'charset': 'utf8', 
    'use_unicode': True, 
    'get_warnings': True, 
    'autocommit':True 
  } 
 
conn = mysql.connector.connect(**config) 
cur = conn.cursor() 
 
def time_me(fn): 
  def _wrapper(*args, **kwargs): 
    start = time.time() 
    fn(*args, **kwargs) 
    seconds = time.time() - start 
    print u"{func}函数每{count}条数数据写入耗时{sec}秒".format(func = fn.func_name,count=args[0],sec=seconds) 
  return _wrapper 
 
#普通写入 
@time_me 
def ordinary_insert(count): 
  sql = "insert into stu(name,age,class)values('test mysql insert',30,8)" 
  for i in range(count): 
    cur.execute(sql) 
 
 
 
#批量 
@time_me 
def many_insert(count): 
  sql = "insert into stu(name,age,class)values(%s,%s,%s)" 
 
  loop = count/20 
  stus = (('test mysql insert', 30, 30), ('test mysql insert', 30, 31), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32) 
         ,('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), 
         ('test mysql insert', 30, 32), ('test mysql insert', 30, 32) 
        ,('test mysql insert', 30, 30), ('test mysql insert', 30, 31), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32) 
         ,('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), 
         ('test mysql insert', 30, 32), ('test mysql insert', 30, 32)) 
  #并不是元组里的数据越多越好 
  for i in range(loop): 
    cur.executemany(sql, stus) 
 
#事务加批量 
@time_me 
def transaction_insert(count): 
  sql = "insert into stu(name,age,class)values(%s,%s,%s)" 
  insert_lst = [] 
  loop = count/20 
 
  stus = (('test mysql insert', 30, 30), ('test mysql insert', 30, 31), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32) 
         ,('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), 
         ('test mysql insert', 30, 32), ('test mysql insert', 30, 32) 
        ,('test mysql insert', 30, 30), ('test mysql insert', 30, 31), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32) 
         ,('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), ('test mysql insert', 30, 32), 
         ('test mysql insert', 30, 32), ('test mysql insert', 30, 32)) 
  #并不是元组里的数据越多越好 
  for i in range(loop): 
    insert_lst.append((sql,stus)) 
    if len(insert_lst) == 20: 
      conn.start_transaction() 
      for item in insert_lst: 
        cur.executemany(item[0], item[1]) 
      conn.commit() 
      print '0k' 
      insert_lst = [] 
 
  if len(insert_lst) > 0: 
    conn.start_transaction() 
    for item in insert_lst: 
      cur.executemany(item[0], item[1]) 
    conn.commit() 
 
def test_insert(count): 
  ordinary_insert(count) 
  many_insert(count) 
  transaction_insert(count) 
 
if __name__ == '__main__': 
  if len(sys.argv) == 2: 
    loop = int(sys.argv[1]) 
    test_insert(loop) 
  else: 
    print u'参数错误'

总结

以上就是本文关于python测试mysql写入性能完整实例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

Python 相关文章推荐
Python中关键字is与==的区别简述
Jul 31 Python
Python中的迭代器漫谈
Feb 03 Python
python中lambda与def用法对比实例分析
Apr 30 Python
django通过ajax发起请求返回JSON格式数据的方法
Jun 04 Python
Python 字典与字符串的互转实例
Jan 13 Python
Python中分支语句与循环语句实例详解
Sep 13 Python
python2.7实现邮件发送功能
Dec 12 Python
详解python中的time和datetime的常用方法
Jul 08 Python
Python单元测试与测试用例简析
Nov 09 Python
jupyter notebook 的工作空间设置操作
Apr 20 Python
Python自然语言处理之切分算法详解
Apr 25 Python
Python趣味挑战之用pygame实现简单的金币旋转效果
May 31 Python
浅谈flask截获所有访问及before/after_request修饰器
Jan 18 #Python
flask中主动抛出异常及统一异常处理代码示例
Jan 18 #Python
浅谈Django学习migrate和makemigrations的差别
Jan 18 #Python
Python机器学习logistic回归代码解析
Jan 17 #Python
酷! 程序员用Python带你玩转冲顶大会
Jan 17 #Python
Python建立Map写Excel表实例解析
Jan 17 #Python
Python冲顶大会 快来答题!
Jan 17 #Python
You might like
php array_merge下进行数组合并的代码
2008/07/22 PHP
探讨各种PHP字符串函数的总结分析
2013/06/05 PHP
PHP+JS实现大规模数据提交的方法
2015/07/02 PHP
PHP实现接收二进制流转换成图片的方法
2017/01/10 PHP
基于Codeigniter框架实现的student信息系统站点动态发布功能详解
2017/03/23 PHP
怎么让脚本或里面的函数在所有图片都载入完毕的时候执行
2006/10/17 Javascript
javascript 写类方式之四
2009/07/05 Javascript
一段实现页面上的图片延时加载的js代码
2010/02/11 Javascript
javascript中的prototype属性使用说明(函数功能扩展)
2010/08/16 Javascript
JS定时刷新页面及跳转页面的方法
2013/07/04 Javascript
JavaScript中获取鼠标位置相关属性总结
2014/10/11 Javascript
javascript中CheckBox全选终极方案
2015/05/20 Javascript
JS实现超简洁网页title标题跑动闪烁提示效果代码
2015/10/23 Javascript
通过Tabs方法基于easyUI+bootstrap制作工作站
2016/03/28 Javascript
jQuery设置Cookie及删除Cookie实例分析
2016/04/15 Javascript
BootStrap modal模态弹窗使用小结
2016/10/26 Javascript
js的三种继承方式详解
2017/01/21 Javascript
基于vue的fullpage.js单页滚动插件
2017/03/20 Javascript
Scala解析Json字符串的实例详解
2017/10/11 Javascript
node使用promise替代回调函数
2018/05/07 Javascript
jQuery使用each遍历循环的方法
2018/09/19 jQuery
如何根据业务封装自己的功能组件
2019/04/19 Javascript
详解vue 图片上传功能
2019/04/30 Javascript
[01:32:50]DOTA2-DPC中国联赛 正赛 DLG vs XG BO3 第一场 1月25日
2021/03/11 DOTA
Python使用正则表达式实现文本替换的方法
2017/04/18 Python
Python3实现计算两个数组的交集算法示例
2019/04/03 Python
Windows下python3安装tkinter的问题及解决方法
2020/01/06 Python
Tensorflow 使用pb文件保存(恢复)模型计算图和参数实例详解
2020/02/11 Python
美国南加州的原创极限运动潮牌:Vans(范斯)
2016/08/05 全球购物
中国第一家杂志折扣订阅网:杂志铺
2016/08/30 全球购物
澳大利亚个性化儿童礼品网站:Bright Star Kids
2019/06/14 全球购物
大学军训通讯稿
2014/01/13 职场文书
护士长竞聘书
2014/03/31 职场文书
消防安全责任书
2014/04/14 职场文书
导游词之永济鹳雀楼
2020/01/16 职场文书
pycharm安装深度学习pytorch的d2l包失败问题解决
2022/03/25 Python