2007年10月04日

SQLite性能評価その1

SQLiteの性能を少し見てみたいと思い、 テーブルに100000件のデータを追加した時の処理時間を測ってみました。
テーブルには以下のように文字列と整数の2列を用意しました。

CREATE TABLE test1(name TEXT,value INTEGER)

nameの方は、ランダムなアルファベットで構成される20文字の文字列で、valueの方も乱数としました。

測定環境

測定環境は以下の通りです。

コンパイラVisual C++.NET 2003デフォルトコンパイラ
OSWindows XP Professional SP2
CPUAMD Athlon 64 3700+
メモリ2GB
HDDSeagate 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 | トラックバック
コメント
コメントする









名前、アドレスを登録しますか?