场景: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。