最近有需求是需要将一个近1200万数据量的del文件导入我们的数据库,并且这个文件的结构与我们的库中的正式表结构不同,并且有重复数据,所以需要先进行去重操作再插入到 正式表中! 之前没做过大数据处理,这件吃了不少苦头算是基本解决了难题,现在记录下来;

首先这del文件中没有包含主键,所以我只能创建一个与之结构一样的中间表,用工具先将其上传至服务器,然后用xshell连接数据库所在的服务器,再连接到db2数据库,用命令: db2 "load from /home/wlth.txt of del insert into UWP_CUST.T_CRM_START" 导入到中间表中,这速度是真的快,几秒就倒进去了!

然后需要将之重复数据去掉,由于没有主键,并且是由两列来区分一个唯一数据,查了一下大概有10万的重复数据,刚开始用常规的group by 做,结果一条sql硬是执行了一个多小时,最后执行到报错回滚都没去掉重。。。 然后想想办法,,增加了一列临时列temp,然后将那两列拼成 字符串 复制到这临时列中,然后对此临时列 创建索引, 之后再对此临时列用group by 做分组去重,这一下子速度就起飞了,去掉重只花了2分钟

然后就需要导入表中了,,我用的是 insert into select ,都说这比传统的插入快,但是却不知道实际效率有多快,我以为会和之前导入一样就几秒钟,结果让我失败了,,,一条SQL执行几分钟之后就报了日志被填满的异常,也就是一个事务太大了就会出现这个问题,之后将自动提交关掉,用 ALTER TABLE UWP_CUST.T_CRM_START ACTIVATE NOT LOGGED INITIALLY 语句将这张表日志关掉,再往里面插,结果插了一个小时都没查完,然后   界面上只能看到当前执行了多长时间,,,也不知道进度如何,,然后一不小心网断了,然后失败,由于处于一个事务所以导致一条数据都没插进去,之后我讲的想办法,尽量减小事务的大小,要是能看到导入的进度就好了,,所以我决定用jdbc 做,,不在数据库工具中导入了,,, 之后写Java代码,,,用循环分页的方法,,分批次导入,并且记录每批次导入用时,这样正好 满足了 既能知道当前导入的进度,又能减小事务的大小,,还能控制在发生异常时,从失败的地方开始导入数据,节省时间!  

最终我以5万条作为一个批次插入,大约每批次花费50秒,,插了N个小时插了进去,,哈哈,算是成功完成了任务,,