robin_77
偷懒是一种必备素质

场景:A表,汇总数据计算目标表。

字段 类型 说明 备注
type 枚举值 数据类别 有多种数据类型
num 浮点数 积分值  
index 长整型 排名位置  
uuid 字符型 业务唯一键 一个用户的唯一性标识

A表数据原料出处:B,C,D,E表。

num 是根据uuid从B,C,D,E表中各取一个字段,按照一定公式,计算而得出来。

A表中,每种type的目前潜在数据量是100W左右,共计十几种type.

—————————————————————————————————————————

业务处理流程(分批计算)

1.第一次计算:数据计算
每批计算5W条数据,将5W的数据插入A表;
再处理下一批,直到所有数据处理完成。

2.第二次计算:排名算法处理
update A t1 set t1.index=((select count(1) from A) - (select count(1) from A t2 where t2.num < t1.num))

——————————————————————————————————————————

改进方案:仅做一次计算,完成数据计算和排名计算。
在处理第一批5W数据的时候,预先算出第一批数据在整体的排名?

欢迎一起讨论讨论...

后续优化....

————————————————————————————————————————————————

优化方案一:SQL优化,说明:oracle数据库,用到了rank函数,id是A表主键,自己通过ID关联自己,用rank函数,比上面的效率高很多

merge into A t using (select id,rank() over (order by num desc) ranks from A) bb

on (t.id = bb.id)

when matched then

  update set t.index = bb.ranks; 

感谢DB同事-wangkui 给出的建议。

补充材料:

1)oracle rank函数 

基本语法:RANK ( ) Over ( [query_partition_clause] order_by_clause ) 

说明:

 

Rank ( ):根据 ORDER BY 子句中运算式的值,从查询返回的每一行,计算他们与其他行的相对位置。组内的资料按 ORDER BY 子句排序,然后给每一行赋一个行号,从而形成一个序列。该序列从1开始,往后累加。每次 ORDER BY 运算式的值发生变化时,该序列也随之增加。有同样值的行得到同样的数字序号(认为 null 时相等的)。

 

使用 Rank ( ) 函数时,如果两行得到同样的排序,则序数将随后跳跃。若两行叙述为1,则没有序数2,序列将给组中的下一行分配值3。

2)oracle dense_rank函数

基本语法:Dense_Rank ( ) over (  [query_partition_clause] order_by_clause)

说明:与rank函数唯一的不同就是若两行序数为1,下一个序数是2,不会跳为3。

 

posted on 2016-07-13 10:58  robin_77  阅读(617)  评论(0编辑  收藏  举报