可阅读原文:http://c.raqsoft.com.cn/article/1541400226267?r=alice
保险行业中,往往需要根据往年保单来快速计算和生成当年新的保单。以车险为例,在提醒老客户续保时就需要计算指定时间段的往年保单,例如某省级公司需要定期计算特定月份内可续保保单对应的历史保单。而目前在大多数保险营运系统中,这类批量数据处理任务都是由存储过程实现的,其中存在的典型问题就是存储过程性能差,运行时间长。如果只是计算一天的历史保单,运行时间尚可接受;如果时间跨度较大,运行时间就会长的无法忍受,基本就变成不可能完成的任务了。
解决思路与过程
案例场景说明
下面我们将针对这种基于历史保单信息的计算任务的性能优化。实际业务中遇到的真实的存储过程很长,有2000多行。我们这里对问题进行了简化,只分析主体的部分,进而讨论集算器SPL语言优化类似计算的方法和思路。
这个场景中计算用到的数据表包括:保单表和保单-车辆明细表。对于较大的省份,保单表和保单-车辆明细表都有几千万数据存量,每天新增保单的增量数据有一到两万条。
经过简化的两个表结构如下:
保单表
policyid char(22) not null ,-- 保单编码(主键)
policyno char(22),-- 保单号
startdate datetime year to second,-- 开始日期
enddate datetime year to second-- 结束日期
保单 - 车辆明细表
policyid char(22) not null , -- 保单编码(主键)
itemid decimal(8,0) not null ,-- 明细编码(主键)
licensenoid varchar(20),-- 牌照编码
licensetype char(3),-- 牌照种类
vinid varchar(18),--vin 编码
frameid varchar(30),-- 车架编码
新旧保单的对照表:
policyid char(22) not null , -- 保单编码
oldpolicyid char(22)—上年保单编码
往年保单的计算输入参数是起始日期(istart)和结束日期(iend),计算目标是新旧保单的对照表,找不到旧保单的将被舍弃。
计算过程简化描述如下:
1、 从保单表中,找出开始日期在指定时间段(istart和iend之间)内的新增保单。
2、 用新增保单关联上一年的历史保单。关联的条件是:vin编码相同;或者车架编码相同;或者牌照种类、牌照编码同时相同。同时,要去掉旧的保险单号为null或者空字符串的数据,去掉新旧保险单相同的数据。
3、 在所有旧保险单中找到和新保单结束日期在90天之内的,就是上年保单。
优化思路
1、 理解业务,采用更好的算法,而不是照搬存储过程。
存储过程如果遇到了很难优化的性能问题,根本原因可能是采用的计算方法出了问题。这往往是因为SQL原理和模型造成的,要靠新的工具通过支持更好的计算方法来解决。如果用SPL简单翻译存储过程的语句,计算方法没有改变,性能也很难提升。
推荐的做法是通过存储过程理解业务的需求,然后从原理层面思考更快的算法,在工具层面采用集算器SPL提供的更优化的算法重新实现。
乾学院提供了很多性能优化的案例,可以帮助SPL程序员快速找到更好的计算方法。
2、 数据外置,利用集算器获得更好性能。
集算器提供了私有数据文件格式,具备压缩、列存、有序等有利于性能的特点。因此可以将数据库中的数据预先缓存到集算器数据文件中,利用数据外置优化整体性能。
3、 针对对关联计算,区别分类加以优化。
和SQL的关联计算不同,集算器中能够对不同类型的join采用不同的算法,包括主键相同的同维表、外键表、主子表、大表关联小表等等细分情况。而如果出现了两个大表cross join的情况,则有必要重新分析业务需求。
具体的解决方法和优化可看原文:http://c.raqsoft.com.cn/article/1541400226267?r=alice
作者:terminator
来源:乾学院
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。