🎨2、多行多列多分隔符拆分
我们先来看看原始数据的,再来尝试拆分
🍋代码:
SELECT REGEXP_SUBSTR (PH,'[^/|\|//|*]+',1,LEVEL) PH, REGEXP_SUBSTR (S杂,'[^/|\|//|*]+',1,LEVEL) S杂 from ( select PH,S杂 from qz_zb_cpjcjg where 1=1 and PH is not null and S杂 is not null and rownum<=2 ) qz_zb_cpjcjg CONNECT BY REGEXP_SUBSTR (PH,'[^/|\|//|*]+',1,LEVEL) is not null or REGEXP_SUBSTR (S杂,'[^/|\|//|*]+',1,LEVEL) is not null
🍋效果:
🍋解析:
当出现2行,第一列为3个值,第二列为4个值,此时拆分的总行数为(1+2+4+8)*2行=30行,当我们把行数改为3行的时候发现拆分后的结果为(1+3+9+27)*3行=120行,当我们将行数改成4行时拆分结果为(1+4+16+64)*4=340行。此时我们发现当行数增加时,我们拆分的总行数会出现规律性的增长,即 (1+n+n²+n³)*n=n+n²+n³+n^4,其中n为你计算的行数,最大次幂为最大的拆分项。因此当我们的行数越多,并且拆分的项目越多时,我们最后拆分出的项数也会越大,当我们的行数为64行,拆分的项10个时,此时拆分的效率就会非常低。
🎈三、 处理超亿亿。。。亿级别数据量
如图所示,我们拆分一个项目用了一个小时都没计算出来,后来测试我将所有的缓存区占用了也没计算出来。看来我们直接用上面拆分的办法好像针对这种多行的情况有点行不通了。
现实中我们有80-90项,并且至少有几百行,因此如此庞大的数据,最后拆分出来的结果会是超亿亿。。。亿级别,即会比10^64还要多的多。如果我们将10^64定义为不可思议,因此我们将这个拆分结果叫做“太不可思议”吧。因为它是上亿个不可思议组成的。所以,面对我们只有128G内存的服务器来处理这种级别的数据量看来是行不通了,难道只有放弃了嘛?
🎨1、我们思考下?
我们发现我们拆分单行数据的时候效率还是非常高的,因此我们需要找到统计的最小单元,并且最小单元的行数不能超过10行,不能拆分的计算结果耗时将是你不能接受的。我们思考我们本次的需求为统计每人每天的工作量,因此我们最先想到的是按天为最小维度来统计。即我们先统计昨天的工作量,再来统计今天的工作量。再汇总历史的工作量和今天的工作量就对应是每个人的所有工作量,再取个平均值就可知工作量是否饱和了。
🎨2、但是这合理吗?
开始小编也是这么去做的,然而发现数据量还是不小,因为。。。。
🎨 3、多行转换为单行拆分结果后统计
因为业务说,这情况就是这样,而且不能改变。因此我去找到了最小单位。即按单行拆分,最终在不到1秒就完成了所有工作量的拆分。最终保存每个检测项目对应日期的人的工作量数据。
🎨 4、最终效果
🎨5、解析
最终拆分通过存储过程的游标循环拆分,将对应拆分明细保存到同一个表中再汇总分析,得出最后的工作量,因太晚了,就暂时不介绍详细的拆分逻辑了。如想获取最终的存储过程拆分逻辑,欢迎留言讨论~