何も考えないとinsertに時間がかかる

こんな感じのコードで何も考えずに 4500件ほどのデータをinsertしてみた。

for (int i=0;i<myData.size();i++) {
	ContentValues values = new ContentValues();
	MyData d = myData.get(i);
	values.put(COLUMN_PHOTOID, d.PhotoID);
	values.put(COLUMN_DAL, d.Dal);
	values.put(COLUMN_DOL, d.Dol);
	values.put(COLUMN_GAIN, d.Gain);
	values.put(COLUMN_NAME, d.Name);
	values.put(COLUMN_DESC, d.Desc);
	values.put(COLUMN_NUM, d.Num);
	values.put(COLUMN_IID, d.IId);

	long result = db.insert(TABLE_NAME, null, values);
}

結果、このループにかかる時間は 5分ちょっと! ビックリ!


で、いくらなんでもおかしいよね?と思って調べてみたらこんなページ発見。

なるほど、insertの実行の度にトランザクションが行われると。
なので毎回行うのではなくこのループの前後をトランザクションで囲んで一回で済ませてしまえば良い。

というわけで、SQLiteDatabaseのページに載ってるサンプルのままにサクっとループを囲んでみた。

db.beginTransaction();
try {
    for (int i=0;i<myData.size();i++) {
    	ContentValues values = new ContentValues();
    	MyData d = myData.get(i);
    	values.put(COLUMN_PHOTOID, d.PhotoID);
    	values.put(COLUMN_DAL, d.Dal);
    	values.put(COLUMN_DOL, d.Dol);
    	values.put(COLUMN_GAIN, d.Gain);
    	values.put(COLUMN_NAME, d.Name);
    	values.put(COLUMN_DESC, d.Desc);
    	values.put(COLUMN_NUM, d.Num);
    	values.put(COLUMN_IID, d.IId);

    	long result = db.insert(TABLE_NAME, null, values);
    }
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}

結果、この処理にかかる時間は 1.5秒弱!
200倍のスピード?
正直、ちょっと信じられなかったので手で書き出したデータを調べてみたりしたけど、問題なくちゃんと書き出せてた。


Twitterでつぶやいたときに「Androidに限らずDBはこういった動きをする」と教えていただいた。
DBのこと、しっかり勉強した方が良いかな…。