トランザクションを使ってSQLiteの処理を超高速化

スポンサード リンク

諸事情で70万弱のデータをデータベース(SQLite3)に格納することがあったのですが、処理が長引きすぎてサーバ側で強制終了。

マニュアルを読んで見つけた「トランザクション」を使ってみると、処理速度が劇的に向上。そして、数秒のうちに格納完了。あまりの早さにビックリしたので、スクリプト実行時間を計測して比較してみました。

データベースの操作はPDOで行いました(PDOしか使ったことがない)。
PHP: PDO - Manual

比較した2つのスクリプト

サンプルスクリプト1(トランザクション不使用)

同じSQL文を100回実行するスクリプト。データベースへのパスは適当。

//開始
$start = microtime(true);

//データベースへの接続
$db = new PDO('sqlite:./test.db');

//レコードの追加
$sql = "insert into test (data) values ('123456789');";
for($a=0;$a<100;$a++){
  $db->query($sql);
}

//終了
$end = microtime(true);

//実行時間の算出
$time = ($end - $start) * 1000;
echo $time.'ミリ秒';

サンプルスクリプト2(トランザクション使用)

サンプルスクリプト1に「トランザクションの開始」と「コミット」を追加しただけ。

//開始
$start = microtime(true);

//データベースへの接続
$db = new PDO('sqlite:./test.db');

//トランザクションの開始
$db->beginTransaction();

//レコードの追加
$sql = "insert into test (data) values ('123456789');";
for($a=0;$a<100;$a++){
  $db->query($sql);
}

//コミット
$db->commit();

//終了
$end = microtime(true);

//実行時間の算出
$time = ($end - $start) * 1000;
echo $time.'ミリ秒';

比較した結果

それぞれ3回ずつ実行し、平均の実行時間で比較してみました。

トランザクション不使用 727.94ミリ秒
トランザクション使用 20.29ミリ秒

比較方法には問題があると思うけど、トランザクションを使った方が明らかに早い。不使用の35倍の早さですからね・・・圧倒的です。件数が多くなるほど、この差が開きそうだ。


スポンサード リンク

関連している記事をピックアップ。あわせてご覧ください。

Twitter始めました。気軽にフォローしてくださいね!
Twitter始めました。気軽にフォローしてくださいね!

    • 通りすがりの名無し
    • 2011/01/29 13:52

    これは「トランザクションを使った」というより、
    コミット実行の頻度を下げたのではないでしょうか。

    前:INSERT:100回 COMMIT:100回
    後:INSERT:100回 COMMIT:1回

  1. マニュアルの「トランザクション」という言葉をそのまま持ってきたのですが、語弊があったならば申し訳ありません。

    • 栗きんとん大統領
    • 2011/07/28 17:47

    トランザクションを使わない例ではSQL文を実行する度にディスクへの書き込みが発生するが、トランザクションを使う場合には最後にコミットした段階でのみディスクへの書き込みが発生したために高速化したのだと思います。

    • 通りすがり
    • 2011/09/26 12:35

    SQLiteでINSERTやUPDATE等の排他ロックが必要なSQLを実行した場合、特に明示しなければ「SQLの実行毎に」自動的にトランザクション処理が行われます。※これをAutoCommitモードと呼び、設定を変更する事が可能です。

    つまり、1000回実行すれば1000回DBに排他ロックがかかる訳で、その分遅くなってしまうわけです。

    SQLを1000回実行する前後でトランザクションを明示すれば、AutoCommitは自動的にOFFになります。
    ロック処理は明示した1回だけ行われますので、その分高速化されます。

  1. 2009年 10月 4日
    トラックバック先 :技術志向
「名前」「メールアドレス」「ウェブサイト」は空欄でもかまいません。