记一次百万数据excel导入数据库的处理过程
生活随笔
收集整理的這篇文章主要介紹了
记一次百万数据excel导入数据库的处理过程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
場景:現在需要導入賬號角色關系數據,數據量:10萬----百萬。之前代碼處理邏輯復雜,運用poi導入技術,業務處理中操作數據庫為單次操作,訪問數據庫次數多,最后批量導入為同步導入,導致數據量過大時,接口響應時間很長。
分析:
首先,excel數據量過大,導入數據也需要驗證操作,此處為了省事,采用easyexcel進行大數據量的導入;
第二:將業務進行拆分梳理,業務中會有刪除操作,對于excel中賬號關聯的角色關系需要進行刪除,我們這里將所有賬號梳理出來進行批量刪除,使操做數據庫的次數減少;刪除時,數據量沒有超過10萬,操作一次數據路;超過10萬,每10萬分批刪除。
第三:向數據庫批量新增數據時,采用多線程處理。2萬條數一個線程,每個線程里2000條數據插入一次。
改進結果:10萬數據處理完不到1分鐘,100萬數據不到4分鐘。
注意:多線程的參數要根據數據量進行合理的配置,否則線程無用。
以下是部分代碼片段:
list拆分方法:
/*** 把list拆分成指定大小的list* @param resList* @param count* @param <T>* @return*/public <T> List<List<T>> splitList(List<T> resList, int count) {if (resList == null || count < 1)return null;List<List<T>> ret = new ArrayList<List<T>>();int size = resList.size();if (size <= count) {// 數據量不足count指定的大小 ?ret.add(resList);} else {int pre = size / count;int last = size % count;// 前面pre個集合,每個大小都是count個元素 ?for (int i = 0; i < pre; i++) {List<T> itemList = new ArrayList<T>();for (int j = 0; j < count; j++) {itemList.add(resList.get(i * count + j));}ret.add(itemList);}// last的進行處理 ?if (last > 0) {List<T> itemList = new ArrayList<T>();for (int i = 0; i < last; i++) {itemList.add(resList.get(pre * count + i));}ret.add(itemList);}}return ret;} /*** 多線程處理入庫操作* @param list* @param ipAddress* @param userName* @param appId*/public void MultithreadingInsert(List<UserAppRole> list,String ipAddress ,String userName,String appId,String toBimStatus) {// 初始化線程池ThreadPoolExecutor threadPool = new ThreadPoolExecutor(20, 50,4, TimeUnit.SECONDS, new ArrayBlockingQueue(50), new ThreadPoolExecutor.AbortPolicy());// 對拆分的集合進行批量處理, 先拆分的集合, 再多線程執行List<List<UserAppRole>> splitList = splitList(list, 20000);// 記錄單個任務的執行次數CountDownLatch countDownLatch = new CountDownLatch(splitList.size());for (List<UserAppRole> userAppRoles : splitList) {// 線程池執行threadPool.execute(()->{log.info("current thread:"+Thread.currentThread()+" is running");try {Integer addNum = 0;if (userAppRoles != null && userAppRoles.size() > 0) {//新增List<List<UserAppRole>> splitRoleList = splitList(userAppRoles, 2000);for (List<UserAppRole> addUerAppRoles : splitRoleList) {addNum += userAppRoleDao.insertByBatch(addUerAppRoles);}}log.info("current thread:"+Thread.currentThread()+" is running over , data size:"+addNum);}catch (Exception e){log.error(e.getMessage());}finally {countDownLatch.countDown();}});}try {// 讓當前線程處于阻塞狀態,直到鎖存器計數為零countDownLatch.await();} catch (InterruptedException e) {throw new RuntimeException("線程執行失敗");}finally {//刪除緩存cacheService.remove(RedisKeyUtils.getUserAppRoleKey(appId));}}總結
以上是生活随笔為你收集整理的记一次百万数据excel导入数据库的处理过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 运维基本功(十六):远程管理SSH服务
- 下一篇: 深度解析互联网下一个十年C位:5G下的物