日期:2014-05-16 浏览次数:20817 次
? ? 项目框架:springmvc+spring3+mybatis
? ? 数据库:mysql5.5
? ? 服务器是阿里云的,但实际上阿里云的机器是万网的,配置为
?
? ??,
?
? ? 有这么一个需求,就是需要批处理向数据库一次性插入50000条数据,当时对表做了分区,开始是只用一次插入操作插入50000条数据,debug时到执行插入的时候就突然卡住了,卡到我的耐心资源超时,所以就把它咔嚓了。然后改了代码,换成一个java For 循环,一次只插1000条数据循环50次插入,大约7.3秒插入完成。接着又换成每次插10000条,分循环5次插入,时间为6.4秒。没道理一次50000需要这么久的时间,于是昨天临走前机器没关,让它跑一次50000条的插入,看看究竟会怎样。第二天早上发现插入失败,日志打了异常:
?
?
? ??org.springframework.dao.TransientDataAccessResourceException:?
### Error updating database. ?Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (3500111 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.
### The error may involve com.yiliwu.ecouponcard.core.dao.EcKeyMapper.insertBatch-Inline
### The error occurred while setting parameters
### Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (3500111 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.
; SQL []; Packet for query is too large (3500111 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.; nested exception is com.mysql.jdbc.PacketTooBigException: Packet for query is too large (3500111 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.
? ? 可见mysql服务器端的参数max_allowed_packet设置过小了,它默认是1M,而我们提交的Packet有3M。登录服务器,找到mysql的配置文件my.cnf,在[mysqld]下加上max_allowed_packet=16M,保存重启mysql后,一次插入50000条成功,耗时7.2秒。
?
? ?对于在for循环中插入数据库操作会造成多次IO性能损耗,必然会在一定程度上减慢插入速度,所以循环50次与循环5次的差异还是可以看到的,7.3>6.4,但是一次50000条的耗时为7.2还是耐人琢磨,我将它暂时归为不完全归纳造成的误差,毕竟不同时段主机的忙闲还是会有些差异的,理论上应该会更快。