トランザクションと更新処理にかかる時間
SQLiteでは明示的にトランザクションを開始しない場合、INSERT、UPDATE、DELETEの前後にBEGIN、COMMITが実行される。ということは
data.each {|d| db.execute('insert into test values(?, ?)', *d) }
こう書くよりも
db.transaction do data.each {|d| db.execute('insert into test values(?, ?)', *d) } end
こう書いた方が処理時間が短くなるはず。
実際にどれぐらいの差があるかを調べてみる。
#!/usr/bin/ruby require 'sqlite3' require 'benchmark' db1 = SQLite3::Database.new('test1.db') db2 = SQLite3::Database.new('test2.db') sql = <<SQL create table test( name varchar(255), mail varchar(255) ); SQL db1.execute(sql) db2.execute(sql) sql = "insert into test values('hoge', 'hoge@hogehoge.com')" Benchmark.bm do |x| x.report('no transaction') { 100.times {db2.execute(sql) } } x.report('transaction ') { db1.transaction do 100.times {db1.execute(sql) } end } end puts db1.get_first_value('select count(*) from test') puts db2.get_first_value('select count(*) from test')
user system total real transaction 0.431000 0.000000 0.431000 ( 0.431000) no transaction 17.895000 0.000000 17.895000 ( 17.894000) 100 100
予想以上の差。更新処理を繰り返す場合は、明示的にトランザクションを開始した方がよさそう。