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的设计模式编程
Mar 01 Python
Django返回json数据用法示例
Sep 18 Python
Python正则简单实例分析
Mar 21 Python
Python3安装Scrapy的方法步骤
Nov 23 Python
python队列queue模块详解
Apr 27 Python
python sys,os,time模块的使用(包括时间格式的各种转换)
Apr 27 Python
Python 判断图像是否读取成功的方法
Jan 26 Python
python入门:argparse浅析 nargs='+'作用
Jul 12 Python
Python操作MySQL数据库的示例代码
Jul 13 Python
python3获取控制台输入的数据的具体实例
Aug 16 Python
Python自定义sorted排序实现方法详解
Sep 18 Python
简单且有用的Python数据分析和机器学习代码
Jul 02 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中显示数组与对象的实现代码
2011/04/18 PHP
PHP中调用ASP.NET的WebService的代码
2011/04/22 PHP
php的mkdir()函数创建文件夹比较安全的权限设置方法
2014/07/28 PHP
php传值赋值和传地址赋值用法实例分析
2015/06/20 PHP
PHP入门教程之数组用法汇总(创建,删除,遍历,排序等)
2016/09/11 PHP
Laravel框架路由设置与使用示例
2018/06/12 PHP
PHP simplexml_import_dom()函数讲解
2019/02/03 PHP
分享8个Laravel模型时间戳使用技巧小结
2020/02/12 PHP
Using the TextRange Object
2006/10/14 Javascript
高亮显示web页表格行的javascript代码
2010/11/19 Javascript
jQuery中的ajax async同步和异步详解
2015/09/29 Javascript
AngularJS基础 ng-submit 指令简单示例
2016/08/03 Javascript
手机端点击图片放大特效PhotoSwipe.js插件实现
2016/08/24 Javascript
js处理层级数据结构的方法小结
2017/01/17 Javascript
Javascript基础回顾之(三) js面向对象
2017/01/31 Javascript
详解Vue.js入门环境搭建
2017/03/17 Javascript
Swiper自定义分页器使用详解
2017/12/28 Javascript
详解VUE-地区选择器(V-Distpicker)组件使用心得
2018/05/07 Javascript
解决ng-repeat产生的ng-model中取不到值的问题
2018/10/02 Javascript
vue 解决uglifyjs-webpack-plugin打包出现报错的问题
2020/08/04 Javascript
jQuery实现查看图片功能
2020/12/01 jQuery
js简单粗暴的发布订阅示例代码
2021/01/23 Javascript
Python算法之栈(stack)的实现
2014/08/18 Python
apache部署python程序出现503错误的解决方法
2017/07/24 Python
Windows系统下多版本pip的共存问题详解
2017/10/10 Python
Python实现定时备份mysql数据库并把备份数据库邮件发送
2018/03/08 Python
使用python socket分发大文件的实现方法
2019/07/08 Python
python 项目目录结构设置
2020/02/14 Python
Python绘制组合图的示例
2020/09/18 Python
python 实现的车牌识别项目
2021/01/25 Python
公司委托书范本
2014/04/04 职场文书
高考寄语大全
2014/04/08 职场文书
解决MySQL存储时间出现不一致的问题
2021/04/28 MySQL
手把手教你用SpringBoot将文件打包成zip存放或导出
2021/06/11 Java/Android
Java 语言中Object 类和System 类详解
2021/07/07 Java/Android
在MySQL中你成功的避开了所有索引
2022/04/20 MySQL