日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

记一次百万数据excel导入数据库的处理过程

發布時間:2024/1/1 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 记一次百万数据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导入数据库的处理过程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。