注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

分享,态度 ·~~

—— 十年太长,五年;如果可以回到五年前,你最想对那时候的自己说什么?

 
 
 

日志

 
 

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

2013-12-05 17:35:46|  分类: Android |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
之前对于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到本地文件的时间,所以优化效果还是非常可观。
  评论这张
 
阅读(10058)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017