初级想法
刚拿到任务时,以为就是拿文件的数据与数据库中的数据比较。没什么大不了的,可是数据量过大,不管是后台还是数据库都承受不了,文件导入时文件不可过大,本想在前台进行切割文件然后逐一进行上传,可是前台也受不了,最后只能人为进行对文件切割每个文件不管是大小和数据量都有限制,不然后台占用访问长,后台自动断掉,数据不完整。自己就在读文件时直接在后台写入redis缓存中,虽然时间有些长,但是至少数据保存住了,可以进行查询比较。减少数据库的访问次数。
遇到问题:1、导入文件过大、数据量大导致访问时间长,-----------------人工进行切割,每个文件的数据量在18万条左右,大小在10m左右。
2、需求不明确,自己没弄懂---------------开发时,需求是不明确的,自己仍要继续进行设计,让整个项目设计满足需求,每次都是问别人细节问题,殊不知整个需求自己都没弄懂
3、对比数据量在万级别,数据全放到后台跑不开,------------导入文件时直接导入redis中(自己使用map类型的有键值对的,以比较的关键字为键),保证一边数据是完整的,然后从数据库中取出几千条数据和redis中数据的键比较,一样的移除留住不一样的,然后将自己标记的数据遍历取出来放到页面中
中级想法
以上比较数据慢,是实时的比较,前台等的时间过长,很有可能直接断掉。开始在表上做手脚。然后导入文件时直接按条 读取,每100条数据时就访问数据库insert数据,最后将数据保存在数据库中,所有的对账直接用SQL跑。语句用的是左连接右连接直接找出两个表中的差异数据
1 select * from t1 left join t2 where t1.id = t2.id and t2.id is null 2 union 3 select * from t1 right join t2 where t1.id = t2.id and t1.id is null
where 后面的条件自己按需求添加。
遇到问题: 1、SQL跑的时间慢,数据量在百万级。-----------------首先自己想到的是分页只差不几条慢慢展示给用户。可是SQL跑的是对最后的结果进行分页,最关键的左右连接的时间没有减少
2、实时对账时间慢-------------------------直接改变对账方式,首先需要创建对账任务(参数设定好,开始任务时直接去)直接查询可以分多少批(总数/一页多少条),然后后台用定时任务处理,在每条记录后添加一个是否比较的字段,一样的勾上。查询时直接查勋两个信息表没对上的数据,主要是开始了分批跑,取出一批数据(只取关键比较的一个字段)时,直接放到list中并在mybatis中遍历放到in语句里跟另一个表所有数据比较,自己根据自己的查询条件建立索引,不然相当慢,当所有批都跑完之后修改任务状态为完成状态,下次任务就取不到这个任务了
1 update t_pay_core_order t1,t_pay_bill_file_detail t2
2 set t1.is_check = 1,t2.is_check = 1
3 WHERE
4 t1.pay_order_no = t2.pay_order_no
5 and t2.pay_order_no in
6 <foreach item="payOrderNo" index="index" collection="orderlist" open="(" separator="," close=")">
7 #{payOrderNo,jdbcType=VARCHAR}
8 </foreach>
9 and t1.trans_date >= #{startTime,jdbcType=INTEGER}
10 and t1.trans_date <= #{endTime,jdbcType=INTEGER}
11 and t1.pay_channel_id = #{payChannelId,jdbcType=TINYINT}
12 and t1.trans_type = #{transType,jdbcType=TINYINT}
这是我mybatis里的SQL语句。目前还是可以跑起来的。
后期优化
导入数据使用银行接口减少人工导入文件的干预,将接口暴露且使用定时任务进行拉取必要的数据(默认为昨天的数据,传参数指定收款与付款)该接口也可用于页面的按钮参数固定,指定日期直接导入数据
ps:关注一下本人公众号,每周都有新更新哦!