Python MySQLdb 循环插入execute与批量插入executemany性能分析(list批量写法亲测成功)
用Python連接MySQL數據庫時,會用到MySQLdb庫,這里下載↓↓↓
https://pypi.python.org/pypi/MySQL-python/
這個庫提供了對數據庫的普遍操作,增刪改查之類的,教程可以參考:
python下的MySQLdb使用
其中,有一個很cooooooooooool的功能就是批量操作executemany,可以進行多行插入
先寫sql語句。要注意的是里面的參數,不管什么類型,統一使用%s作為占位符
 例如,向user表(username,salt,pwd)插入數據
sql = 'INSERT INTO 表名 VALUES(%s,%s,%s)'
 對應的param是一個tuple或者list
param = ((username1, salt1, pwd1), (username2, salt2, pwd2), (username3, salt3, pwd3))
這樣就包含了三條數據,通過executemany插入
 n=cursor.executemany(sql,param)?
 上個雙休日在學校往畢設系統里導名單,想到Java就心累于是用Python寫
作為一個老實的土鱉,在知道有這個酷炫的方法情況下,還是有點不敢用,先保守地寫了一個循環的版本
幾百條數據很快就導進去的,本來這就該結束了,但是又覺得有點不甘心,想知道兩種插入方式效率有多大差別
于是簡單模擬了10000個用戶的數據,試著用兩種方法各跑了一遍
# -------------------------------------------
 # Python MySQLdb 循環插入execute與批量插入executemany性能分析
 # 插入數據量:10000條
 # 每條字段:username, salt, pwd
 # Author : Lrg
 # -------------------------------------------
 # encoding = utf-8
 import MySQLdb
 import xlrd
 import time
 import sys
 reload(sys)
 sys.setdefaultencoding("utf-8")
 ?
 # 從users.xls文件獲取10000條用戶數據
 # 該文件由create_users.py生成
 def get_table():
 ?? ?FILE_NAME = 'users.xls'
 ?? ?data = xlrd.open_workbook(FILE_NAME)
 ?? ?table = data.sheets()[0]
 ?? ?return table
 ?
 # 循環插入execute?? ?
 def insert_by_loop(table):
 ?? ?nrows = table.nrows
 ?? ?for i in xrange(1,nrows):
 ?? ??? ?param=[]
 ?? ??? ?try:
 ?? ??? ??? ?sql = 'INSERT INTO user values(%s,%s,%s)'
 ?? ??? ??? ?# 第一列username,第二列salt,第三列pwd
 ?? ??? ??? ?print 'Insert: ',table.cell(i, 0).value, table.cell(i, 1).value, table.cell(i, 2).value
 ?? ??? ??? ?param = (table.cell(i, 0).value, table.cell(i, 1).value, table.cell(i, 2).value)
 ?? ??? ??? ?# 單條插入
 ?? ??? ??? ?cur.execute(sql, param)
 ?? ??? ??? ?conn.commit()
 ?? ??? ?except Exception as e:
 ?? ??? ??? ?print e
 ?? ??? ??? ?conn.rollback()
 ?? ?print '[insert_by_loop execute] total:',nrows-1
 ?
 # 批量插入executemany
 def insert_by_many(table):
 ?? ?nrows = table.nrows
 ?? ?param=[]
 ?? ?for i in xrange(1,nrows):
 ?? ??? ?# 第一列username,第二列salt,第三列pwd
 ?? ??? ?param.append([table.cell(i, 0).value, table.cell(i, 1).value, table.cell(i, 2).value])
 ?? ?try:
 ?? ??? ?sql = 'INSERT INTO user values(%s,%s,%s)'
 ?? ??? ?# 批量插入
 ?? ??? ?cur.executemany(sql, param)
 ?? ??? ?conn.commit()
 ?? ?except Exception as e:
 ?? ??? ?print e
 ?? ??? ?conn.rollback()?? ?
 ?? ?print '[insert_by_many executemany] total:',nrows-1?? ?
 ?
 ?
 # 連接數據庫
 conn = MySQLdb.connect(host="127.0.0.1", port=3306, user="lrg", passwd="lrg", db="pythontest")
 cur = conn.cursor()
 ?
 # 新建數據庫
 cur.execute('DROP TABLE IF EXISTS user')
 sql = """CREATE TABLE user(
 ?? ??? ?username CHAR(255) NOT NULL,
 ?? ??? ?salt CHAR(255),
 ?? ??? ?pwd CHAR(255)
 ?? ??? ?)"""
 cur.execute(sql)
 ?
 # 從excel文件獲取數據
 table = get_table()
 ?
 # 使用循環插入
 start = time.clock()
 insert_by_loop(table)
 end = time.clock()
 print '[insert_by_loop execute] Time Usage:',end-start
 ?
 # 使用批量插入
 start = time.clock()
 insert_by_many(table)
 end = time.clock()
 print '[insert_by_many executemany] Time Usage:',end-start
 ?
 # 釋放數據連接
 if cur:
 ?? ?cur.close()
 if conn:
 ?? ?conn.close()
 一共10000條數據
一行行循環execute,耗時200秒左右(下面244秒的數據是每次循環加了輸出語句的,應該有點影響)
而用executemany一次提交全部,耗時只有0.86秒……
[insert_by_loop execute] total: 10000
 [insert_by_loop execute] Time Usage: 244.164735527
 [insert_by_many executemany] total: 10000
 [insert_by_many executemany] Time Usage: 0.861406346583
 [Finished in 245.7s]
土鱉現在有一種難以言喻的微妙感
 想起前兩天用正則表達式用的正爽時,看到一篇文章說,同樣的功能用字符串函數完成比正則快幾十幾百倍……
討厭啦泥們不要欺負新手啊!!【捂臉】
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
附上生成模擬數據user.xls的代碼,簡單粗暴(MD5部分實驗程序:Python簡單密碼加密程序,加鹽(salt)md5)
# -------------------------------------------
 # Python生成user程序
 # Author : Lrg
 # -------------------------------------------
 # encoding = utf-8
 from random import Random
 from hashlib import md5
 import xlwt
 ?
 # 獲取由4位隨機大小寫字母、數字組成的salt值
 def create_salt(length = 4):
 ?? ?salt = ''
 ?? ?chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
 ?? ?len_chars = len(chars) - 1
 ?? ?random = Random()
 ?? ?for i in xrange(length):
 ?? ??? ?# 每次從chars中隨機取一位
 ?? ??? ?salt += chars[random.randint(0, len_chars)]
 ?? ?return salt
 ?
 # 獲取原始密碼+salt的md5值
 def create_md5(pwd,salt):
 ?? ?md5_obj = md5()
 ?? ?md5_obj.update(pwd + salt)
 ?? ?return md5_obj.hexdigest()
 ?
 # 創建一個xls文件
 book = xlwt.Workbook()
 # 創建一個sheet
 sheet = book.add_sheet('users', cell_overwrite_ok=True)
 # 每列第一行寫上列名
 sheet.write(0, 0, 'username')
 sheet.write(0, 1, 'salt')
 sheet.write(0, 2, 'pwd')
 # 生成user數量
 count = 10000
 # 第一個id
 first_id = 311010000
 for i in xrange(count):
 ?? ?current_id = str(first_id + i)
 ?? ?salt = create_salt()
 ?? ?pwd = create_md5(current_id, salt)
 ?? ?sheet.write(i+1, 0, current_id)
 ?? ?sheet.write(i+1, 1, salt)
 ?? ?sheet.write(i+1, 2, pwd)
 # 保存
 book.save('users.xls')
 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
過了一天,又學到一個打臉方法
MySQL本身有個load data infile的方法,格式類似這樣:
load data infile 'D:/Python workspace/user.txt' into table user(username, salt, pwd)
這個方法有多快?
 從txt導5個字段的9086條數據到mysql,先讀到程序里,再用executemany是0.29秒,直接用這個語句導的話,0.17秒……
想到昨天一個上午都在磨磨唧唧研究循環跟批量,這下被打臉也是打的有點爽……
 ————————————————
 版權聲明:本文為CSDN博主「尾巴七」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
 原文鏈接:https://blog.csdn.net/colourless/article/details/41444069
總結
以上是生活随笔為你收集整理的Python MySQLdb 循环插入execute与批量插入executemany性能分析(list批量写法亲测成功)的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 什么样的情况下手机不能给汽车加油?
- 下一篇: 为什么首保后油耗会降低?
