10,000件のデータをInsertしてみて1件ずつのCommitと
全件InsertしてからCommitした場合で実行時間を確認してみた。

サンプルコード

# coding: utf-8

try:
 # import

 import mysql.connector
 import string
 from random import randrange


 # 接続
 connect = mysql.connector.connect(user='root', password='password', host='localhost', database='test', charset='utf8')

 # カーソル
 cursor = connect.cursor()
 # SQL 発行
 # cursor.execute('select language_id,name from language',())

 for i in  range(0, 10000):

  # Random Charactor Create
  LENGTH = 20
  alphabets = string.digits + string.letters

  def randstr(n):
      return ''.join(alphabets[randrange(len(alphabets))] for i in xrange(n))
  if __name__ == '__main__':


   randstr_ins =  randstr(LENGTH)
   insert_stmt = 'insert into language(name) values("%s")' % randstr_ins
   cursor.execute(insert_stmt)
   #print insert_stmt
   #connect.commit()

 else:
    print('Finish Creating Data')

 # フェッチ
 #
 # rows = cursor.fetchall()
 # print(rows)
 connect.commit()
 cursor.close()
 # 切断
 connect.close()

except Exception as myout:

 print(myout)

■全てのデータInsertが完了してからCommitした場合

1回目
$ time python mysql_loop.py
Finish Creating Data

real 0m2.017s
user 0m0.000s
sys 0m0.062s

$

2回目
$ time python mysql_loop.py

real 0m1.917s
user 0m0.000s
sys 0m0.015s

$

3回目(100,000件で試してみた)
$ time python mysql_loop.py
Finish Creating Data

real 0m17.972s
user 0m0.000s
sys 0m0.031s

$

   randstr_ins =  randstr(LENGTH)
   insert_stmt = 'insert into language(name) values("%s")' % randstr_ins
   cursor.execute(insert_stmt)
   #print insert_stmt
   #connect.commit()

 else:
    print('Finish Creating Data')

 # フェッチ
 #
 # rows = cursor.fetchall()
 # print(rows)
 connect.commit()

■1件Insert毎にCommitした場合

1回目
$ time python mysql_loop.py
Finish Creating Data

real 0m5.950s
user 0m0.000s
sys 0m0.031s

$

2回目
$ time python mysql_loop.py
Finish Creating Data

real 0m6.006s
user 0m0.000s
sys 0m0.062s

$

3回目(100,000件で試してみた)
$ time python mysql_loop.py
Finish Creating Data

real 0m58.563s
user 0m0.000s
sys 0m0.046s

$

   randstr_ins =  randstr(LENGTH)
   insert_stmt = 'insert into language(name) values("%s")' % randstr_ins
   cursor.execute(insert_stmt)
   #print insert_stmt
   connect.commit()

 else:
    print('Finish Creating Data')

 # フェッチ
 #
 # rows = cursor.fetchall()
 # print(rows)
 # connect.commit()

結果

mysql> select * from language order by language_id desc limit 0,10;
+-------------+----------------------+---------------------+
| language_id | name                 | last_update         |
+-------------+----------------------+---------------------+
|       80300 | TFEGGvjH8b74uFawV7OS | 2014-08-05 10:11:14 |
|       80299 | ZMAF25n87TaIjgT8qJgr | 2014-08-05 10:11:14 |
|       80298 | sxV2CjebjaMpmOlQe9Yf | 2014-08-05 10:11:14 |
|       80297 | s9c0avx5UumRtcPdtDRu | 2014-08-05 10:11:14 |
|       80296 | MH0M5t7jD9F2jGs3jbM4 | 2014-08-05 10:11:14 |
|       80295 | Ap4ThCp5RsFHAOrUw0BV | 2014-08-05 10:11:14 |
|       80294 | cwLz0e8Vx5L73rzJd6uW | 2014-08-05 10:11:14 |
|       80293 | FAfnZReIagqi4mgCnsSV | 2014-08-05 10:11:14 |
|       80292 | YfxFjzfJVATB5sEHnkR0 | 2014-08-05 10:11:14 |
|       80291 | wENaU30qX4aF51tpDSfY | 2014-08-05 10:11:14 |
+-------------+----------------------+---------------------+
10 rows in set (0.00 sec)

mysql>

mysql> SELECT @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ       |
+-----------------------+

mysql>

※ やはりCommitの回数が少ない方が断然早い。

※ InnoDB のデフォルト分離レベルは、REPEATABLE-READなので、
  Commitが終わったものが見る事が出来ます。
  Selectをバッチ中に確認すると1回毎にCommitしているQueryは、
  Selectを実施する毎にその時の最新の状況を確認する事が出来ます。

Reference: 13.5.10.3. InnoDB と TRANSACTION ISOLATION LEVEL
http://dev.mysql.com/doc/refman/5.1/ja/innodb-transaction-isolation.html

Comments are closed.

Post Navigation