问题描述
在使用开源ORMLite数据库组件时,为了测试需要,写了个异步任务循环生成10000条数据,代码如下:
/**
* 创建数据测试数据
* @author JacenChiu
*/
private class CreateTestDataForDb extends AsyncTask<Integer, Void, Long>{
public int countPerTime = 10000;
@Override
protected void onPreExecute(){
super.onPreExecute();
}
@Override
protected Long doInBackground(Integer... params){
long startTime = System.currentTimeMillis();
for(int i=1; i<=10000; i++){
ClaxxDao.createOrUpdate(new Claxx("测试班级" + i));
Message message = new Message();
message.what = 1;
message.obj = i + "/" + countPerTime;
mCreateProgressHandler.sendMessage(message);
}
long endTime = System.currentTimeMillis();
return endTime - startTime;
}
@Override
protected void onPostExecute(Long result){
Message message = new Message();
message.what = 1;
message.obj = "耗时【" + (result/1000) + "】秒";
mCreateProgressHandler.sendMessage(message);
Toast.makeText(getApplicationContext(),
"创建数据完成,耗时【" + (result/1000) + "】秒!", Toast.LENGTH_LONG).show();
Log.d("MainActivity", "--创建数据完成,耗时【" + (result/1000) + "】秒!");
Intent intent = new Intent(Constant.ACTION_REFREASH_CLASS);
mContext.sendBroadcast(intent);
super.onPostExecute(result);
}
}
在GalaxyS4执行上面的代码,发现这1w条数据居然要耗时195s才完成,如下图:
原因分析
之所以会耗时那么久,是因为ORMLite每次执行ClaxxDao.createOrUpdate(new Claxx("测试班级" + i))时都会自动提交数据,而不是在最后统一提交数据的,这样相当于commit了1w次。
如果要提高效率就必须关闭该DAO的自动提交功能,并开启事务,在所有数据的insert语句都生成后,统一一次commit。
解决方案
通过下面的ORM事务的代码改造,可以将1w条数据插入时间缩短到14s:
/**
* 创建数据测试数据
* @author JacenChiu
*/
private class CreateTestDataForDb extends AsyncTask<Integer, Void, Long> {
public int countPerTime = 10000;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Long doInBackground(Integer... params) {
// ORMLite的数据连接封装类
AndroidDatabaseConnection adc = null;
adc = new AndroidDatabaseConnection(DatabaseHelper.getHelper().getWritableDatabase(), true);
// 设置要开启事务的DAO不自动提交代码
RuntimeExceptionDao<Claxx, String> dao = DatabaseHelper.getHelper().getClaxxDao();
dao.setAutoCommit(adc, false);
// 存储点名称为create_claxx
Savepoint sp = null;
try {
sp = adc.setSavePoint("create_claxx");
long startTime = System.currentTimeMillis();
for (int i = 1; i <= 10000; i++) {
dao.createOrUpdate(new Claxx("测试班级" + i));
Message message = new Message();
message.what = 1;
message.obj = i + "/" + countPerTime;
mCreateProgressHandler.sendMessage(message);
}
// 成功添加后统一提交数据
adc.commit(sp);
long endTime = System.currentTimeMillis();
return endTime - startTime;
} catch (SQLException e) {
e.printStackTrace();
try {
// 发生异常时进行回滚
adc.rollback(sp);
} catch (SQLException e1) {
e1.printStackTrace();
}
return 0l;
}
}
@Override
protected void onPostExecute(Long result) {
Message message = new Message();
message.what = 1;
message.obj = "耗时【" + (result / 1000) + "】秒";
mCreateProgressHandler.sendMessage(message);
Toast.makeText(getApplicationContext(),
"创建数据完成,耗时【" + (result / 1000) + "】秒!", Toast.LENGTH_LONG).show();
Log.d("MainActivity", "--创建数据完成,耗时【" + (result / 1000) + "】秒!");
Intent intent = new Intent(Constant.ACTION_REFREASH_CLASS);
mContext.sendBroadcast(intent);
super.onPostExecute(result);
}
}
本文为JacenChiu原创,转载请注明出处。