现状资料说明:
需求背景介绍:
1. 该文件功能是以 .csv 后缀的文件进行解析后,反查我方数据库表,取出账单后做具体的处理业务
2. 该文件功能主要分为以下几个环节
- 获取URL并下载文件
- 文件解析并检查文件数据的有效性及数据去重
- 取出文件中的具体业务字段进行查询我方的库表
- 根据查询出来的账单做具体的业务处理
3. 处理百万量级以上数据时,整体效率偏低,理想情况的是处理百万量级的数据控制在一个小时左右
注:该文件处理功能是在单线程的情况下执行,暂时不需要考虑太消耗性能来开多线程的处理方案
流程耗时分析:
文件去重后以资产号查询我方账单集合,整体是从 7ms ~ 22ms 不等;理论上来说文件数据有多少条就会查询多少次库表
结论:通过核实代码逻辑,该功能文件的执行文件耗时,均为在查询DB这块占用耗时较多
如:对到170W+的数据量,需要耗时2个半小时左右执行完。现文件执行流程耗时也算相应合理。也存在要提高文件处理性能的必要性
问题点:
现SQL的查询逻辑等同于
select * from postloan_#xx#_db.t_asset_bill_#y# where Fstatus=1 and Fasset_id=xxxx
1. 这里是返回的整个账单集合;如 asset_id 对应的数据有12条账单数据,则返回了12条记录的一个list对象
2. 重新评估业务后,这样的SQL查询是可以进一步优化
3. 全量字段查询是没有必要的,影响磁盘IO的处理效率
注:该库表为百库十库,库表字段数量超过一百个字段
设计方案:
优化思路:
1. 从查询整个账单集合返回 --> 查询最大期账单返回
2. 全字段账单数据返回 --> 精简需要字段的返回
业务逻辑优化:
1. 获取文件中资产号,通过资产号入参。返回提前结清的账单的最大期数账单对象
2. 提供该 getSimpleLastTermBillByAssetId 查询方法,mapper 文件的查询SQL同步调整字段精简返回
-- 根据资产号查询提前结清最大期数的账单(字段精简版本)
select
Fid,Floan_channel_id,Fasset_id,Fbill_id,Fcus_order_id,Finsure_mode_no,Frepay_term,Freal_repay_data,Freal_repay_type
from
postloan_#xx#_db.t_asset_bill_#y#
where
Fstatus=1 and Fasset_id=xxxx and Floan_term=Frepay_term and freal_repay_type = 30 and Fpostloan_repay_source_type in (0,20)
3. 获取到我方提前结清的账单对象后(已做字段精简),对符合退保的账单进行组装MQ发出 (现有的处理逻辑中退保校验条件减少)
注:这里是将代码逻辑中的一部分校验条件前置到SQL查询中实现,减少业务代码逻辑
效率提升效果:
扣款回盘文件退保性能提升需求(线上观察)
a.整体文件处理性能提升 100~110%
b.账单查询优化后由 7~22ms 下降到 2~6ms
优化总结:
1. 通常情况下程序中文件处理效率低,都是在解析文件的过程中有查询DB的情况;若只是解析文件做业务处理话,百万量级的数据也就只是几秒钟程序就能跑完
2. 数据库表查询,若非必要,应当根据业务使用场景;第一优先选择为需要字段SQL查询来提高查询效率,减少磁盘IO与内存的消耗
参考资料:
MySQL:查询字段数量多少对查询效率的影响 http://blog.itpub.net/7728585/viewspace-2668552/