您的位置:首页 > 移动开发 > Android开发

Android:SQLite插入大量数据的效率优化

2017-01-17 16:31 501 查看
转载地址:http://zwkufo.blog.163.com/blog/static/2588251201311552757473/

之前对于ContentResolver.applyBatch的理解其实有偏差,导致插入大量数据到SQLite时,耗时很久。通常,在用ContentResolver.applyBatch插入数据时,会这样写代码:

        ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
// Do something.
operations.add(ContentProviderOperation
.newUpdate(uri)
.withValue(key1, value1)
.withValue(key2, value2)
....
.build());
// Do something.
cr.applyBatch(authority, operations);

原以为上面的代码中,ContentResolver帮忙处理了事务机制。但事实上applyBatch传入的每条ContentProviderOperation都包含Uri,而ContentResolver并不会记录或者比较Uri的异同;所以它把每条ContentProviderOperation都当作独立的操作,这确实是符合ContentResolver.applyBatch的设计的。在这种情况下,用applyBatch一次处理1000条数据和单独insert
1000次数据到DB其实是一样的。

真正的解决方案是,需要显示引入SQLite的Transaction机制。

以实际项目为例,是一个ContentProvider。在继承ContentProvider的子类中override名为bulkInsert的函数,加入transaction的支持:

    @Override
public int bulkInsert(Uri uri, ContentValues[] values) {
// Do something.

SQLiteDatabase db = mDbHelper.getWritableDatabase();
db.beginTransaction();
try {
int count = values.length;
for (int i = 0; i < count; i++) {
if (db.insert(tableName, null, values[i]) < 0) {
return 0;
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
return values.length;
}

并且改用ContentResolver.bulkInsert方法来批量insert:

        ContentValues[] cnttValues = new ContentValues[size];
// Do something.
cr.bulkInsert(uri, cnttValues);

经测试,1000左右的数据插入总耗时从40s降到2s左右——已经包括写log到本地文件的时间,所以优化效果还是非常可观。

【本文链接:http://zwkufo.blog.163.com/blog/static/2588251201311552757473/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  性能优化 数据 sqlite