SQLiteの性能を少し見てみたいと思い、
テーブルに100000件のデータを追加した時の処理時間を測ってみました。
テーブルには以下のように文字列と整数の2列を用意しました。
CREATE TABLE test1(name TEXT,value INTEGER)
nameの方は、ランダムなアルファベットで構成される20文字の文字列で、valueの方も乱数としました。
測定環境は以下の通りです。
コンパイラ | Visual C++.NET 2003デフォルトコンパイラ |
OS | Windows XP Professional SP2 |
CPU | AMD Athlon 64 3700+ |
メモリ | 2GB |
HDD | Seagate ST3300622AS |
プロジェクト設定 | デフォルトRelease構成 |
SQLiteバージョン | 3.4.2 (not define THREADSAFE) |
SQLiteは、「SQLiteの使い方(Visual C++.NET 2003)」で 紹介した方法で静的ライブラリにして、アプリケーションからC Interfaceで呼び出すようにしました。
SQLiteは、大量のINSERTを実行する場合は、最初にトランザクションを明示的に開始しておかないとパフォーマンスがとても悪くなるというデータベースです。
(「生まれ変わるPHP - Zend Engine 2、SQLiteの実力は?」に参考情報があります)
まずこれを確認してみました。
トランザクションを開始しない方をCase1とします。 コードは以下のようになります。
// Case1 struct sqlite3* Db; char Buffer[256]; sqlite3_open("testdb.sq3", &Db); sqlite3_exec(Db, "CREATE TABLE test1(name TEXT,value INTEGER)", NULL, NULL, NULL); // 処理時間測定開始 for (int i = 0; i < 100000; ++i) { char* Sql = sqlite3_snprintf(sizeof(Buffer), Buffer, "INSERT INTO test1 VALUES('%q',%d)", StringList[i].c_str(), ValueList[i]); sqlite3_exec(Db, Sql, NULL, NULL, NULL); } // 処理時間測定終了 sqlite3_close(Db);
トランザクションを明示的に開始する方をCase2とします。 コードは以下のようになります。
// Case2 struct sqlite3* Db; char Buffer[256]; sqlite3_open("testdb.sq3", &Db); sqlite3_exec(Db, "CREATE TABLE test1(name TEXT,value INTEGER)", NULL, NULL, NULL); // 処理時間測定開始 sqlite3_exec(Db, "BEGIN", NULL, NULL, NULL); for (int i = 0; i < 100000; ++i) { char* Sql = sqlite3_snprintf(sizeof(Buffer), Buffer, "INSERT INTO test1 VALUES('%q',%d)", StringList[i].c_str(), ValueList[i]); sqlite3_exec(Db, Sql, NULL, NULL, NULL); } sqlite3_exec(Db, "COMMIT", NULL, NULL, NULL); // 処理時間測定終了 sqlite3_close(Db);
測定結果は以下のようになりました。
データベースのopen、closeや、CREATE TABLEの時間は含めていません。
Case2が見えなくなるくらい違いがあります。Case1の処理時間はCase2の約1500倍。ここまでとは・・・。
「SQLiteの性能評価その2」に続きます。
投稿者 MASATO : 2007年10月04日 00:40 | トラックバック