最近在做数据迁移工作,已有一堆数据文件,要把这些数据文件写到MySQL 数据库里面去。
MySQL数据库上架了一层服务接口,可以直接调用。博主写了一个迁移程序,放在服务器A上。
**************背景介绍完毕*******************
第一次发现数据文件迁移缓慢时,博主的反应是:服务器A性能不好。 那就给A加内存,加CPU!再开台服务器B,还要开多个进程,同时迁移!
过了一段时间,发现还是很慢。 博主的反应是:多打日志,看慢在哪吧。。。加了后就发现300多行数据插入,居然要十几秒,震惊了!
于是博主觉得,是不是网络不好。这个时候看了下新开的B,发现挺快的啊。。。博主更加认定是网络问题,A和B怎么一个好一个就不好呢。。。赶紧找IT看看...
可是,可是IT说这两台服务器没什么区别。。。
肿么会呢。。。
博主不相信啊。。。
几个小时候后再看了看B,发现B也变慢了。。。。。
有同事说,是不是没有批量插入呀。。。肿么可能呢,用的是jdbctemplate的batchupdate接口呢。。。
可是也没有别的办法了。。。博主只好怀疑下这个接口。。。
google一番,还真有人提到一个很重要的知识。batchupdate接口要真实现批量的话,得在连接数据库的时候设置两个属性。
那就是jdbc:mysql//host:port?useServerPrepStmts=false&rewriteBatchedStatements=true
关于这两个属性,我就不细说了,有需要的请戳这里
知道这么个事实,博主激动啊。。。赶紧添上,期待能看到飞一般的迁移速度!
然而,博主失望了。。。为啥呢。。。为啥呢。。。别人都说加了这两个参数,速度至少提升10倍啊。。。怎么到博主这就啥反应也没有呢。。。
是不是还是没有批量!!!先想想,batchupdate到底是怎么帮忙批量的。。。
继续google...
知道了,原来是因为insert into A values(a,b,c),(d,e,f),(g,h,i)...;比N条单独的insert into A values(x,x,x);要快很多!
那是不是因为博主的程序里面有什么问题,导致batchupdate没能帮博主拼成values(a,b,c),(d,e,f)...这种形式呢。。
果然,因为博主用到了MySQL的一个特殊用法,ON DUPLICATE KEY UPDATE ,博主是这么用的:
insert into A(id,name,age) values(1,'小明',‘5’) ON DUPLICATE KEY UPDATE name='小明', age='5';
这就是问题所在啊!
应该要这么写:
insert into A(id,name,age) values(1,'小明',‘5’) ON DUPLICATE KEY UPDATE name=VALUES(name), age=VALUES(age);
这样写的话,通过看MySQL日志就可以看到,MySQL收到的执行语句就是:
insert into A(id,name,age) values(1,'小明',‘5’), values(2,'小王',‘6’),(3,'小张',‘3’) ON DUPLICATE KEY UPDATE name=VALUES(name), age=VALUES(age);
最后,博主改了一通代码,插入1000多条数据只要200多毫秒啦~~~~~~~~~~~
扯了很多废话。。。。。。
博主想说,遇到问题,要有耐心。。。。
遇到难题,要怀疑一切可以怀疑的。。。
听上去,是不是可以总结为,遇到问题,不要偷懒,动手去测试。哈哈哈哈哈哈
网友评论