美文网首页小技巧
[Android] 提高ORMLite插入大量数据效率的解决方案

[Android] 提高ORMLite插入大量数据效率的解决方案

作者: JacenChiu | 来源:发表于2016-05-18 17:36 被阅读0次

问题描述


在使用开源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才完成,如下图:


插入1w条数据耗时

原因分析


之所以会耗时那么久,是因为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原创,转载请注明出处。

相关文章

网友评论

    本文标题:[Android] 提高ORMLite插入大量数据效率的解决方案

    本文链接:https://www.haomeiwen.com/subject/mqpwrttx.html