JPA的saveAll方法执行效率很差

springboot项目中使用了SpringDataJpa的技术,很方便,省了很多dao层繁琐的步骤,但是有一个接口需要批量更新或者插入,数据量挺大,大概1-2w条,每条记录20-30个字段吧,对于刚工作不久的我还是比较大的。我开始使用的saveAll(),因为本地单元测试,也没考虑那么多(其实更早期更蠢,遍历再save,压根不去考虑数据库连接池的压力或者说每次遍历都要去连接数据库的时间损耗…),但是客户压力测试,我的接口就拉胯了。接口等待时间太久…诶

刚开始的思路想解决saveAll方法为什么这么慢的问题,因为saveAll是有则更新,无则新增,所以每条记录都要去比对该记录是否存在表中,效率比较差(我以后还是用JPA去适应数据量较小的吧,jpa可能还有什么别的路子后面可以配置进去也行)。

最后改用了mybatis的foreach方式,虽然比较老套而且肯定不是最快的办法,但是还是实用。使用过程中,出现了这个报错:Packet for query is too large (3227 > 1024). You can change this value on the server by setting the max_allowed_packet’ variable.
应该是一下子丢进来的数据太大,超过了mysql的限制,有人说通过修改数据库的max_allowed_packet这个属性来修改,不过我这里是jenkins部署的服务器,能操作到数据库的只有navicat这个可视化工具,如果使用命令行修改这个属性,好像只能暂时起效。我只好类似分页,把18000条数据按照2000一次批量操作,分成9次,这样既不会报错,也会比savelAll快一些。后续再研究一下更快更高效的方法。

数据库配置加上allowMultiQueries=true才会支持foreach循环操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值