利用集算器实现分库汇总

当单台数据库的数据量太大而影响性能时,可以把数据拆分到多台服务器上,每台服务器只承担部分计算压力,再由SPL合并计算结果。特殊地,数据可拆分为历史数据库和当前实时数据库,由SPL实现T+0计算。下面用几个典型例子来说明分库汇总的用法。

过滤

订单表orders分库存储在两个Oracle数据库中,数据源名分别为orclA、orclB,请过滤出金额amount大于等于10000的订单。

SPL代码如下:

 ABC
1=[connect("orclA"),connect("orclB")] /连接多个数据源
2select * from orders where amount>=10000 /过滤SQL
3fork A1=A3.query(A2)/并行计算
4=A3.conj() /合并结果

排序

请过滤出金额大于等于10000的订单,并按订单金额顺序排序。

分库排序算法中,各线程的计算结果不能简单合并,而要用merge函数归并,SPL代码如下:

6select * from orders where amount>=10000   order by amount/排序SQL
7fork A1=A7.query(A2) 
8=A7.merge(AMOUNT) /归并

分组汇总

请将订单表按年、月分组,对各组数据的amount字段求和。

分库分组汇总算法中,合并后的数据要做二次分组汇总,SPL代码如下:

10select extract(year from   orderTime)y,extract(month from orderTime)m,sum(amount) amount from orders   group by  extract(year from   orderTime),extract(month from orderTime)/分组汇总SQL
11fork A1=A11.query(A10)/各库分组汇总
12=A11.conj() /合并
13=A12.groups(Y,M;sum(AMOUNT):AMOUNT) /二次分组汇总

如果分组数较多,则应当利用有序来提高性能,具体做法是:在SQL中事先按分组字段排序,使SQL结果有序,之后使用归并算法合并数据,并用group@o分组汇总。SPL代码如下:

14select extract(year from   orderTime)y,extract(month from orderTime)m,sum(amount) amount from orders   group by  extract(year from   orderTime),extract(month from orderTime) order by y,m/分组汇总SQL
15fork A1=A15.query(A14) 
16=A15.merge(Y,M) /归并
17=A16.groups@o(Y,M;sum(AMOUNT):AMOUNT) /有序分组汇总

 

分组汇总后过滤

请将订单表按年、月分组,对各组数据的amount字段求和,再过滤出汇总值大于110000000的结果。

SQL实现本算法,通常在group by后带having语句,即:

select extract(year from   orderTime)y,extract(month from orderTime)m,sum(amount) amt from orders group   by  extract(year from   orderTime),extract(month from orderTime) having sum(amount)>=120000000

分库实现算法时,不能直接使用上述SQL,应该先实现分组汇总算法,再用SPL实现过滤。代码如下:

19select extract(year from   orderTime)y,extract(month from orderTime)m,sum(amount) amt from orders group   by  extract(year from   orderTime),extract(month from orderTime)/无过滤的SQL
20fork A1=A20.query(A19)/各库分组汇总
21=A20.conj() /合并
22=A21.groups(Y,M;sum(AMT):AMT) /二次分组汇总
23=A22.select(AMT>=110000000) /最后过滤
24=A1.(~.close()) /关闭多个连接

 

异构库分库

SPL除了支持同构库分库,也支持异构库分库。需要注意的是,不同数据库的SQL语法并不通用,比如数字截断函数,Oracle中写作trunc,在MySQL中写作truncate。为了正确处理不同的语法,应当先写出SPL标准SQL,再用SPL的sqltranslate函数翻译成不同的本地SQL。

比如:orders表分库存储在Oracle和mysql中,数据源名为orcl和my,请查询amount字段大于等于10000的记录,并将amount字段截断取整。

SPL代码如下:

 ABC
1=[[connect("orcl"),"ORACLE"],[connect("my"),"MYSQL"]]/连接数据源,标记数据库类型
2select ORDERID,ORDERTIME,truncate(AMOUNT,0),CLIENTID,SALESID   from orders where amount>=10000 /标准SQL
3fork A1=A2.sqltranslate(A3(2))/转为本地SQL
4 =A3.query(B3)/查询
5=A3.conj() /合并结果

 

连接

除了单表分库计算,SPL也支持多表连接分库计算。这种情况下应对事实表和维表分别处理,事实表应当分库存放,每个数据库存放一部分数据,维表不分库,应当全量复制到每一个数据库中。

比如销售人员表sales是订单表orders的维表,两者以salesID为关联字段,请按sales表的部门字段dept分组,求各部门的销售额。假设sales表已全量存储于各数据库,则SPL代码如下:

 ABC
1=[connect("orclA"),connect("orclB")] /连接多个数据源
2select sales.dept,sum(orders.amount)amount   from orders,sales where orders.salesID=sales.salesID group by sales.dept/分组汇总SQL
3fork A1=A3.query(A2)/并行计算
4=A3.conj() /合并结果
5=A4.groups(DEPT;sum(AMOUNT):AMOUNT) /二次分组汇总
6=A3.(~.close()) /关闭连接

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值