kdb - 多列上的缓慢聚合

标签 kdb

这个聚合多列的 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 索引(目前?)仅限于纯矢量数据- 如果能够以某种方式将其应用于 custprod组合,我希望我们会看到像我这样的简单结果查询。)

关于kdb - 多列上的缓慢聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29280070/

相关文章:

performance - 我们可以期待 kdb+ 32bit 的性能

KDB+\q : How to fill regularly spaced time series?

kdb - 替换列表中与 KDB Q 中的子字符串不匹配的元素

kdb - 如何在不使用字符串格式的情况下在远程服务器上执行 kdb 动词函数?

Python + Q (KDB) - 哪些工具易于使用且维护良好

kdb - 查询列表中百分位的有效方法

kdb - 在 kdb 中将列存储为字符串

backup - 如何使用 tplogs 恢复 HDB?

left-join - KDB+ 如何连接特定日期的数据

kdb - 无法将多个参数传递给 kdb 中的每个函数