yumimueの日記

2007-11-02

[][]トランザクションと更新処理にかかる時間 09:04 はてなブックマーク - トランザクションと更新処理にかかる時間 - yumimueの日記

SQLiteでは明示的にトランザクションを開始しない場合、INSERTUPDATEDELETEの前後に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

予想以上の差。更新処理を繰り返す場合は、明示的にトランザクションを開始した方がよさそう。

k3ck3c 2007/11/02 12:10 タイトルの括弧が一つ足りないようです。
SQLiteの話題、参考になります。

ゲスト



トラックバック - http://rubyist.g.hatena.ne.jp/yumimue/20071102