前回の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 |