LoginSignup
11

More than 5 years have passed since last update.

AndroidでSQLiteのパフォーマンス比較(DELETE編)

Last updated at Posted at 2015-02-01

前回のINSERT編に続き、今回はDELETE編。

環境

Nexus5, Android 4.4.4

テーブル

こんなかんじ。深い意味はない。

カラム名 制約
id TEXT PRIMARY KEY
name TEXT NOT NULL
address TEXT
count INTEGER NOT NULL
flag INTEGER NOT NULL

INSERT済みのデータ

前回のINSERT編でINSERTした以下のようなデータ10000件。

id name address count flag
id0 name0 NULL 0 0
id1 name1 NULL 1 0
id2 name2 NULL 2 0
... ... ... ... ...
id9999 name9999 NULL 9999 0

使用メソッド

今回比較したメソッドは以下の3つ。

  • SQLiteDatabase#delete
  • SQLiteDatabase#execSQL
  • SQLiteStatement#executeUpdateDelete

1行削除

1行(id=id5000)をそれぞれのメソッドでDELETEする。

SQLiteDatabase#delete

Androidで一般的な方法。SQLを知らなくても書ける。

db.beginTransaction();
try {
    db.delete("table_name", "id=?", new String[]{"id5000"});
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}
SQLiteDatabase#execSQL

SQLを知っていれば、こちらの方が書きやすい。ただし、戻り値はなし。

db.beginTransaction();
try {
    db.execSQL("DELETE FROM table_name WHERE id=?", new String[]{"id5000"});
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}
SQLiteStatement#executeUpdateDelete

Android3.0から追加された方法。INSERTはこれが一番速かった。

db.beginTransaction();
try {
    final SQLiteStatement statement = db.compileStatement("DELETE FROM table_name WHERE id=?");
    try {
        statement.bindString(1, "id5000");
        statement.executeUpdateDelete();
    } finally {
        statement.close();
    }
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}
結果

結果は以下の通り。1行なのでSQLiteStatementも効果はない。

メソッド 処理時間(msec)
SQLiteDatabase#delete 8.75
SQLiteDatabase#execSQL 8.92
SQLiteStatement#executeUpdateDelete 8.69

ちなみに、PRIMARY KEYでないnameを条件にした場合は以下の通りで当然いずれも遅くなる。

メソッド 処理時間(msec)
SQLiteDatabase#delete 13.71
SQLiteDatabase#execSQL 13.55
SQLiteStatement#executeUpdateDelete 13.49

複数行削除

それぞれのメソッドでN(=1, 5, 10, 50, 100)行ずつ、M(=100, 1000)行DELETEする。
以降のソースはN=5, M=1000の場合。

SQLiteDatabase#delete
db.beginTransaction();
try {
    final String whereClause = "id IN (?,?,?,?,?)";
    final String[] whereArgs = new String[count];
    for (int i = 0, index = 0; i < 10000; i += 10) {
        whereArgs[index++] = "id" + i;
        if (index == 5) {
            db.delete("table_name", whereClause, whereArgs);
            index = 0;
        }
    }
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}
SQLiteDatabase#execSQL
db.beginTransaction();
try {
    final String sql = "DELETE FROM table_name WHERE id IN (?,?,?,?,?)";
    final String[] bindArgs = new String[count];
    for (int i = 0, index = 0; i < 10000; i += 10) {
        bindArgs[index++] = "id" + i;
        if (index == 5) {
            db.execSQL(sql, bindArgs);
            index = 0;
        }
    }
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}
SQLiteStatement#executeUpdateDelete
db.beginTransaction();
try {
    final SQLiteStatement statement = db.compileStatement("DELETE FROM table_name WHERE id IN (?,?,?,?,?)");
    try {
        for (int i = 0, index = 0; i < 10000; i += 10) {
            statement.bindString(++index, "id" + i);
            if (index == 5) {
                statement.executeUpdateDelete();
                index = 0;
            }
        }
    } finally {
        statement.close();
    }
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}
結果

結果は以下の通り。
M=100の場合はN<=5、M=1000の場合はN<=10まではSQLiteStatement#executeUpdateDeleteが速いが、それ以降からどれも変わらなくなる。
100行程度であれば、どのメソッドでも1度に100行DELETEしてよさそう。
それ以上であれば、SQLiteStatementで10〜50行程度ずつDELETEするのがベスト?

N メソッド M=100 M=1000
1 SQLiteDatabase#delete 72.14 258.83
SQLiteDatabase#execSQL 73.09 238.73
SQLiteStatement#executeUpdateDelete 56.50 184.08
5 SQLiteDatabase#delete 55.18 126.14
SQLiteDatabase#execSQL 53.03 84.25
SQLiteStatement#executeUpdateDelete 50.71 74.06
10 SQLiteDatabase#delete 47.86 111.01
SQLiteDatabase#execSQL 49.66 107.33
SQLiteStatement#executeUpdateDelete 48.88 79.59
50 SQLiteDatabase#delete 46.80 77.18
SQLiteDatabase#execSQL 48.83 82.33
SQLiteStatement#executeUpdateDelete 46.20 79.67
100 SQLiteDatabase#delete 47.43 95.91
SQLiteDatabase#execSQL 48.79 92.67
SQLiteStatement#executeUpdateDelete 49.78 94.60

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