LoginSignup
11
13

More than 5 years have passed since last update.

Android: SQLiteインサート高速化で、パフォーマンスのイライラを解消する

Last updated at Posted at 2015-06-29

AndroidのSQLiteでバルクインサートする方法です。

普通にインサートする時

通常のインサート処理
DatabaseHelper dbHelper = new DataBaseHelper();
SQLiteDatabase db = new dbHelper.getWritableDatabase();

//インサートするデータのArrayList
List<ContentValues> valueList = new ArrayList<ContentValues>();

//データ作成
ContentValues values = new ContentValues();
values.put("Name", "hoge");
values.put("Tel", "0000-1234-5678");
values.put("Age", 24);
valueList.add(values);
values = new ContentValues();
values.put("Name", "fuga");
values.put("Tel", "0000-1234-5678");
values.put("Age", 30);
valueList.add(values);

for (ContentValues val : valueList) {
    long ret = db.insert("MyTable", null, val);  
    if (ret < 0) {
        Log.d("ログのタグ", "インサート失敗!!!!!");
    }
}
db.close();

このようにArrayListをLoopで回して1件ずつインサートすると、SQLiteは1件ずつインサートするごとに
トランザクションのコミットを行います。
少量のデータのインサートなら1件ずつトランザクションコミットが走ることは気になりませんが、
大量データとなると、コミットのコストはバカになりません。
そこで、データを全部インサートしたあとに、コミットを行うことで、トランザクションコミットのコストを最小限にすることができます。

バルクインサートする時

バルクインサート処理
// トランザクション開始を宣言
db.beginTransaction();
try {
    for (ContentValues val : valueList) {
        long ret = db.insert("MyTable", null, val);  
        if (ret < 0) {
            Log.d("ログのタグ", "インサート失敗!!!!!");
        }
    }
    //トランザクション成功を宣言。
    db.setTransactionSuccessful();

} finally {
    // トランザクション終了
    db.endTransaction();
    db.close();
}



このように明示的にトランザクションの開始、成功、終了を宣言することで、トランザクションコミットのタイミングをコントロールすることができます。
setTransactionSuccessful()を呼び出すことで、データベースへの変更がコミットされ、呼び出さなければロールバックされます
そのためこの方法には、以下のメリットがあります。

  • 高速化
  • 途中で失敗した場合ロールバックができる

パフォーマンス比較

以下のサイトに比較があったので、貼っつけておきます。約2倍ほど高速です。

http://www.atmarkit.co.jp/ait/articles/0905/20/news111_2.html

1.PNG

11
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
13