[Android] 提高ORMLite插入大量数据效率的解决方案
16lz
2021-01-23
[Android] 提高ORMLite插入大量数据效率的解决方案
问题描述
在使用开源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 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原创,转载请注明出处。
更多相关文章
- android复制数据库到SD卡
- Android 数据库 大量插入 事务开启
- 转:Bitmap造成OOM的讨论与解决方案
- Android使用代码实现关机/重启
- 【知识点】android代码中设置margin
- Android使用SQLite数据库的示例