1. 程式人生 > 資料庫 >python測試mysql寫入效能完整例項

python測試mysql寫入效能完整例項

本文主要研究的是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,class)values(%s,%s,%s)" 
 
  loop = count/20 
  stus = (('test mysql insert',30),('test mysql insert',31),32),32)) 
  #並不是元組裡的資料越多越好 
  for i in range(loop): 
    cur.executemany(sql,stus) 

事務加批量寫入,每次批量寫入20條資料,每20個批量寫入作為一次事務提交

def transaction_insert(count): 
  sql = "insert into stu(name,%s)" 
  insert_lst = [] 
  loop = count/20 
 
  stus = (('test mysql insert',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,8)" 
  for i in range(count): 
    cur.execute(sql) 
 
 
 
#批量 
@time_me 
def many_insert(count): 
  sql = "insert into stu(name,stus) 
 
#事務加批量 
@time_me 
def transaction_insert(count): 
  sql = "insert into stu(name,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寫入效能完整例項的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支援!