7.3.3大数据结果集

在上一节中,我们知道,在执行分组聚合时,可以先将各部分数据分别分组聚合,这样可以获得一组有序的结果序表,再将结果归并就能得到最终结果。使用这样的方法,我们可以计算大数据结果集的分组聚合问题。

所谓大数据结果集,就是指不仅仅计算使用的源数据的数据量巨大,同时计算产生的结果也是大数据,这使得计算的结果集都无法一次读入内存,只能分步读取出来。如电信公司统计每位用户的当月账单,B2C网站统计每种商品的销售情况等,这些数据的统计结果可能会超过几百万条记录。

在集算器中,可以使用cs.groupx() 函数来计算大结果集的分组聚合。在下面我们用商品订单的每日统计结果模拟一下大数据结果集的使用。为了体会内存的限制,这里要求每次只能读取100条记录,那么需要分组聚合计算每天的订单时,必须使用groupx函数:

 

A

1

=file("Order_Wines.txt")

2

=file("Order_Electronics.txt")

3

=file("Order_Foods.txt")

4

=file("Order_Books.txt")

5

=[A1:A4].(~.cursor@t())

6

=A5.conjx()

7

=A6.groupx(Date;count(~):Count,sum(round(decimal(Amount),2)):TotalAmount;100)

8

=A7.fetch(100)

9

=A7.fetch(100)

10

=A7.fetch(100)

11

=A7.fetch(100)

A6中,各个游标中数据依次连接,并非按日期排序。在A7中分组聚合后,将返回游标,而非序表,这样在A8~A11中即可分步读取数据,数据如下:

 

 

其中,A8~A10各读出100天的统计结果,而A11中读出了剩余的数据。游标中的数据全部读出后,将自动关闭。

A7中,使用groupx函数,将数据按日期分组聚合,并设定缓冲行数为100A7中的groupx函数中,最后一个参数100,表示内存中最多容纳100条数据,每100条数据就需缓存数据。这个参数在实际应用中是不需要设定的,集算器在执行缓存时会自动估算当前内存可容纳的数据条数,在必须的情况下才缓存数据。这样,在A7执行时,将边读取游标A6中的数据,边拆分聚合,每出现100行聚合结果,即缓存到一个临时文件中,以此类推。而A7中的计算结果,是由这些临时文件构成的文件组游标:

如果分步执行,那么在A7执行后,可以在系统的临时目录中看到生成的临时文件:

为了更清楚的了解到这些集文件中的内容,可以读出这些文件中的数据,如:

 

A

1

=file("temp/tmpdata1372633253707222252").import@b()

2

=file("temp/tmpdata2669923936558108709").import@b()

3

=file("temp/tmpdata3937021394605697131").import@b()

4

=file("temp/tmpdata8767777617311441973").import@b()

A1A3中读出的数据分别如下:

 

临时文件的名称时随机生成的,从中取出一些文件读取数据,可以看到,每个临时文件中都存储了部分连续的原始记录的分组聚合结果,而且在文件内按照日期完成了排序。实际上,根据函数中的缓冲行数,除了最后一个临时文件,每个文件中都正好包含100个日期的部分汇总数据。使用groupx生成游标,在用这个游标fetch取数时,会将所有的临时文件中的数据再次有序归并后计算出结果。

在使用临时文件的游标取数结束,或者关闭后,涉及的临时文件将自动删除。关于外存分组的计算方式,可以阅读7.5大数据结果集的外存分组原理进一步了解。