解決mybatis-plus 查詢耗時慢的問題
mybatis-plus 查詢耗時慢
1、現象
查出30000多條id
然後用
EntityWrapper ew = new EntityWrapper<>(); ew.in(TableFieldConstant.F_AUTH_RESULT_ID, ids);
查詢會很慢
2、原因
跟瞭一下mybatis-plus源碼
protected String formatSqlIfNeed(boolean need, String sqlStr, Object... params) { if (need && !StringUtils.isEmpty(sqlStr)) { if (ArrayUtils.isNotEmpty(params)) { for(int i = 0; i < params.length; ++i) { String genParamName = "MPGENVAL" + this.paramNameSeq.incrementAndGet(); sqlStr = sqlStr.replace(String.format("{%s}", i), String.format("#{%s.paramNameValuePairs.%s}", this.getParamAlias(), genParamName)); this.paramNameValuePairs.put(genParamName, params[i]); } } return sqlStr; } else { return null; } }
問題出現在
sqlStr = sqlStr.replace(String.format("{%s}", i), String.format("#{%s.paramNameValuePairs.%s}", this.getParamAlias(), genParamName));
對replace 測試 發現當數據量大時替換會很耗時 測試的遍歷瞭30000次拼接從1到30000 替換耗時20多秒
對 apache-commons-lang 的StringUtis.replace測試是耗時7秒多
3、總結
把使用mybaits 批量查詢改為 手寫sql查詢 之後問題解決
使用mybatis-plus批量操作時要謹慎 能寫sql盡量寫sql
這個跟mybatis-plus 的小夥伴提瞭問題後已經解決 可以升級jar版本 3.x
mybatis-plus 處理大數據量太慢
大批量數據插入方法是Mybatis的foreach拼接SQL
我發現不管改成Mybatis Batch提交或者原生JDBC Batch的方法都不起作用,實際上在插入的時候仍然是一條條記錄的插,速度遠不如原來Mybatis的foreach拼接SQL的方法。
// 第一步判斷更新或添加 String[] splitUserId = userGroup.getUserId().split(","); String[] spiltUserName = userGroup.getUserName().split(","); if (StringUtils.isBlank(userGroup.getId())) { userGroup.setNum(spiltUserName.length); userGroupMapper.insert(userGroup); } else { userGroup.setNum(spiltUserName.length); userGroupMapper.updateById(userGroup); } /* 第二部刪除中間表信息,字段冗餘 */ Map<String, Object> columnMap = new HashMap<String, Object>(); columnMap.put("USER_GROUP_ID", userGroup.getId()); groupUsersService.removeByMap(columnMap); /* 第三步,批量保存中間表 */ if (splitUserId.length != 0) { List<GroupUsers> groupUsersList = Lists.newArrayList(); for (int i = 0; i < splitUserId.length; i++) { GroupUsers gu = new GroupUsers(); gu.setUserId(splitUserId[i]); gu.setUserName(spiltUserName[i]); gu.setUserGroupId(userGroup.getId()); groupUsersList.add(gu); } groupUsersService.saveBatch(groupUsersList); }
1、就是這樣的一種情景也很符合大部分的開發場景,可就是1000條數據的情況下用瞭8秒 ,這可能與計算機的性能有很大的關系,但就是如此也不至於用八秒鐘,那麼用戶體驗會很慘的。
2、JDBC連接URL字符串中需要新增一個參數:
rewriteBatchedStatements=true url: jdbc:mysql://192.168.1.143:3306/rt_xxxxxx_test?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true
3、MySQL的JDBC連接的url中要加rewriteBatchedStatements參數,並保證5.1.13以上版本的驅動,才能實現高性能的批量插入。
4、MySQL JDBC驅動在默認情況下會無視executeBatch()語句,把我們期望批量執行的一組sql語句拆散,一條一條地發給MySQL數據庫,批量插入實際上是單條插入,直接造成較低的性能。
隻有把rewriteBatchedStatements參數置為true, 驅動才會幫你批量執行SQL
另外這個選項對INSERT/UPDATE/DELETE都有效
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- 升級到mysql-connector-java8.0.27的註意事項
- 關於MyBatis連接MySql8.0版本的配置問題
- 在IDEA中maven配置MyBatis的流程詳解
- mybatis-plus 使用Condition拼接Sql語句各方法的用法
- Mybatis源碼解析之事務管理