优化MySQL in参数值上限问题:异常“IN items count 2723 exceeds the threshold 2000 at com.mysql.cj.jdbc.exceptions”

简述:今天项目中发现mysql in 最大值超出上限的问题,针对此问题提出相关优化方案,提供大家参考,异常代码如下:

**IN items count 2723 exceeds the threshold 2000
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ~[mysql-connector-j-8.0.31.jar:8.0.31]
at** 

目前,了解有四种方式:

  1. 修改mysql in 参数配置大小值,对与性能有较大压力;
  2. 改成批量查询,切片用户ID,最后再合并数据,这种情况下需要解决分页带来的问题,和数据多差带来的性能消耗;
  3. 改成子查询,目前业务设计跨库查询肯能要迁移到adb处理,改动代码较多,相对于性能比上面两种更好;
  4. 代码切片超出in 参数ID值 , List list 参数,最终入参拼接mysql 执行语句, 类似与:select * from table where a or in () ro a in () 模式,此方法与第二种有点类同,只是把切割方式,拼接参数,作为入参控制in 值大小,次方法对于性能也有弊端,如果list 过大会导致sql 过长问题,或者是性能问题,list 越大,性能越差。

还有更好的优化方式,可以留言讨论~!

正题:

此次优化是针对第4方案,做出的评估方案进行优化

为何选此方案:

1.是根据业务设计来的,历史遗留原因,数据库跨实例,同账号权限分配等原因无法通过,** from a.Y left jon b.U on a.id =b.id 做关系数据查询结果集。

2.评估代码改动较大,目前项目已经运行六七年,UId 贯彻整个系统,如果调整关联查询改动面积较大,需要做更多的评估和可实施方案调研。

3.改动面积小,in 值大小通过参数配置可控,整体性能在控制范围内

代码参考:

ids 分片方法:

	public static <F> List<List<F>> idSplitList(List<F> list) {if (CollectionUtil.isEmpty(list)) {return null;}int groupSize = Integer.valueOf(20);int length = list.size();// 计算可以分成多少组int num = (length + groupSize - 1) / groupSize;List<List<F>> newList = new ArrayList<>(num);for (int i = 0; i < num; i++) {// 开始位置int fromIndex = i * groupSize;// 结束位置int toIndex = Math.min((i + 1) * groupSize, length);newList.add(new ArrayList<F>(list.subList(fromIndex, toIndex)));}return newList;}

mybaits 对应mapper.xml 文件代码

<if test ="idsSlice != null and idsSlice .size >0">and (<foreach collection="idsSlice " item="idsItem" separator=" " index="index" ><if test="index !=0">orif> id in<foreach collection="idsItem" item="item" separator="," close=")" open="(">#{item}foreach>foreach>)
if>

代码解释:

1.idSplitList 方法是对List ids 进行切片分割,按照20个分割一次。

2.xml 解释,此代码语法是参考mybaitis mapper.xml 语法来写的,动态拼接sql, 会基本语法的这大概都能看懂,index 值 要判断第一个下标不用or 拼接sql ,其它下标都需要拼接成:“ where a in () or a in () or a in (*) ” 格式

大致思路就介绍这里,具体可以参考这个链接:
mybatis-plus in查询条件超过1000条报错

备注:选择那种方案,需要根据自己系统的情况来评估选择适合自己的优化方案,如果是ADB库,或者是只读库,建议使用左右链接模式更好,但是如果在业务库又没办法拆分开只能选择折中模式,最终的方案都是为了解决系统瓶颈问题为目的。希望此文章对你有所启发和帮助!

欢迎大家评论区,讨论并提出更好的方案!


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部