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 | トラックバック