这个聚合多列的 kdb 查询大约需要 31 秒,而 J 则需要 3 秒
有没有更快的方法在 kdb 中求和?
最终这将针对 32 位版本上的分区数据库运行
/test 1 - using symbols
n: 13000000;
cust: n?`8;
prod: n?`8;
v: n?100
a:([]cust:cust; prod:prod ;v:v)
/query 1 - using simple by
q)\t select sum(v) by cust, prod from a
31058
/query 2 - grouping manually
\t {sum each x[`v][group[flip (x[`cust]; x[`prod])]]}(select v, cust, prod from a)
12887
/query 3 - simpler method of accessing
\t {sum each a.v[group x]} (flip (a.cust;a.prod))
11576
/test 2 - using strings, very slow
n: 13000000;
cust: string n?`8;
prod: string n?`8;
v: n?100
a:([]cust:cust; prod:prod ;v:v)
q)\t select sum(v) by cust, prod from a
116745
比较J代码
n=:13000000
cust=: _8[\ a. {~ (65+?(8*n)#26)
prod=: _8[\ a. {~ (65+?(8*n)#26)
v=: ?.n#100
agg=: 3 : 0
keys=:i.~ |: i.~ every (cust;prod)
c=.((~.keys) { cust)
p=.((~.keys) { prod)
s=.keys +//. v
c;p;s
)
NB. 3.57 seconds
6!:2 'r=.agg 0'
3.57139
({.@$) every r
13000000 13000000 13000000
更新: 从 kdbplus 论坛,我们可以得出大约 2 倍的速度差异
q)\t r:(`cust`prod xkey a inds) + select sum v by cust,prod from a til[count a] except inds:(select cust,prod from a) ? d:distinct select cust,prod from a
6809
更新 2:为每个 @user3576050 添加另一个数据集 该数据集具有相同的总行数,但每组分布 4 个实例
n: 2500000
g: 4
v: (g*n)?100
cust: (g*n)#(n?`8)
prod: (g*n)#(n?`8)
b:([]cust:cust; prod:prod ;v:v)
q)\ts select sum v by cust, prod from b
9737 838861968
之前的查询在新数据集上运行不佳
q)\ts r:(`cust`prod xkey b inds) + select sum v by cust,prod from a til[count b] except inds:(select cust,prod from b) ? d:distinct select cust,prod from b
17181 671090384
最佳答案
如果您更新此数据的频率低于查询数据的频率,那么预先计算组索引怎么样?创建单个查询的成本大约相同,并且查询速度提高了约 30 倍。
q)\ts select sum v by cust,prod from b
14014 838861360
q)\ts update g:`g#{(key group x)?x}flip(cust;prod)from`b
14934 1058198384
q)\ts select first cust,first prod,sum v by g from b
473 201327488
q)
结果与行顺序和架构详细信息匹配:
q)(select sum v by cust,prod from b)~`cust`prod xasc 2!delete g from select first cust,first prod,sum v by g from b
1b
q)
(顺便说一句,我对 J 基本上一无所知,但我的猜测是它正在计算类似的多列组索引。不幸的是,q 的 g
索引(目前?)仅限于纯矢量数据- 如果能够以某种方式将其应用于 cust
和 prod
的组合,我希望我们会看到像我这样的简单结果查询。)
关于kdb - 多列上的缓慢聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29280070/