一次批量插入数据库上万条记录优化

由于项目涉及到数据库的东西太多太多,基本所有功能都涉及到数据库。在一个移动客户端上只要涉及到网络数据都得保存到本地,数据量小的情况下还好,如果数据量成千上万,那稳定性,速度效率个方面问题层出不穷。

问题:上万条数据从服务端下下来,可能会导致程序崩溃?

解决方案

1.首先这个奔溃问题,我不知道是什么奔溃,然后让业务那边在初选收获功能模块中加一些大数据量我这边好测试,业务分别加成功了4000和9040两种,

2.运行项目,测试了一下,前两次貌似都报了网络环境异常,查看log是com.android.volley.TimeoutError超时,后来再测几次就没出现,估计网络不稳定造成,下载成功后会保存至数据库,下载过程挺快,然后卡在了保存至数据库,加载框也不转了,静静地等着

2.1.如果,在这中间,手指触碰到了安卓事件,系统会弹出ANR对话框,然后强制关闭,系统奔溃。

我认为解决方案就是数据库操作在子线程,可有效避免ANR。

2.2.如果,在这中间,静静地等着数据库插入操作直至完成,下面是测试保存所需等待时间,其实算了操作数据库两个方法。

  •    @Override
                            public void requestSucceed(PrimaryHarvestPlotList object) {
                                // 存储初选收获小区数据
                                long startTime = System.currentTimeMillis();
                                harvestPlanPlotDao.savePrimaryHarvestPlotListBeforeQuery(harvestPlanId, object.getHarvestPlanPlotList());
                                primaryHarvestDao.updateHarvestPlanPlotNum(harvestPlanId, object.getHarvestPlanPlotList().size());
                                long endTime = System.currentTimeMillis();
                                Log.i("khb插入耗时:", (endTime - startTime) / 1000 + "s");
                                refreshFromDB();
                                checkLoadingFinish();
                                ToastUtil.toast(mContext, "[" + harvestPlanName
                                        + "]小区数据下载成功!");
    
                            }
    
数据量4000条9020条
所需时间9s84s

大数据量保存优化

1.使用事物操作,调用userDao.createOrUpdate(userBean)耗时较长,大概为45s左右,userDao.create(userBean)大概为15s左右

public void insertByShiwu(View view) {
        list = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            UserBean userBean = new UserBean("khb" + i, "男", 24);
            list.add(userBean);
        }
        long startTime = System.currentTimeMillis();
        userDao.insertByShiwu(list);
        long endTime = System.currentTimeMillis();
        Log.i("khb插入耗时:", (endTime - startTime) / 1000 + "s");

}


public void insertByShiwu(List<UserBean> userBeans) {

    if (!db.isOpen()) {
        db = dataBaseHelper.getWritableDatabase();
    }
    db.beginTransaction();
    try {
        for (UserBean userBean : userBeans) {
            userDao.createOrUpdate(userBean);
        }
        db.setTransactionSuccessful();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        try {
            if (null != db) {
                db.endTransaction();
                db.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

使用SQLiteStatement,耗时4s左右

  public void insertByStatement(View view) {
        list = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            UserBean userBean = new UserBean("khb" + i, "男", 24);
            list.add(userBean);
        }
        long startTime = System.currentTimeMillis();
        userDao.insertByStatement(list);
        long endTime = System.currentTimeMillis();
        Log.i("khb插入耗时:", (endTime - startTime) / 1000 + "s");

  }


public void insertByStatement(List<UserBean> userBeans) {

        if (!db.isOpen()) {
            db = dataBaseHelper.getWritableDatabase();
        }
        db.beginTransaction();
        String sql = "insert into UserBean (name,sex,age) values (?,?,?)";
        SQLiteStatement stat = db.compileStatement(sql);
        try {
            for (UserBean userBean : userBeans) {
                stat.bindString(1, userBean.getName());
                stat.bindString(2, userBean.getSex());
                stat.bindLong(3, userBean.getAge());
                stat.executeInsert();
            }
            db.setTransactionSuccessful();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (db != null) {
                db.endTransaction();
                db.close();
            }
        }


   }

综上所述,SQLiteStatement 更快一些

------ 本文结束 ------
坚持原创技术分享,您的支持将鼓励我继续创作!