如何在KDB上快速插入数据到磁盘表?

  • 本文关键字:数据 磁盘 插入 KDB kdb
  • 更新时间 :
  • 英文 :


我有大约10,000个符号的5年分条,作为CSV文件。总共大约有50GB的文本。我的内存是32GB。

我试图将所有这些数据加载到一个KDB表中,所以它很容易查询。

symbols: `$(-4_')(string') key `:/home/chris/sync/us_equities
f: {`$(":/home/chris/sync/us_equities/", x, ".csv")}
load_symbol: {(0!(update "P"$-1_/:t, s: x from flip `t`o`h`l`c`v!("*FFFFI";",")0: f(string x))) }
({`:/home/chris/sync/price_data insert (load_symbol x)}) each symbols
  • 我应该使用一个简单的表,或者我应该使用分区/播放?
  • 我正在添加股票作为类型符号的额外列;对吗?
  • 最后一行insert非常慢。看起来需要大约一天的时间来处理,也许更长。我该如何优化它?我试过peach,但这甚至更慢。它看起来开始非常快,并且随着each的每一步变得更慢。

谢谢!

考虑到数据大小和更新频率,不建议在这种情况下使用平面文件。每次插入时都需要从头重新创建文件,导致插入时间与总行数成线性关系。

q)t:([]a:til 10000000;b:til 10000000)
q)`:t set t
`:t
q)t `:t insert t
305
q)t `:t insert t
365
q)t `:t insert t
574
q)t `:t insert t
809
q)t `:t insert t
1236
q)t `:t insert t
2687
q)t `:t insert t
3200

将此与散列表进行比较,在散列表中,新数据中的每一列都被附加到相应的文件中,从而导致常量插入。

q)t:([]a:til 10000000;b:til 10000000)
q)`:t/ set t
`:t/
q)t `:t insert t
166
q)t `:t insert t
101
q)t `:t insert t
97
q)t `:t insert t
100
q)t `:t insert t
111
q)t `:t insert t
113

如果该符号不在文件中,那么明智的做法是将其添加到表中。但是我建议将列命名为sym而不是s. 这只是因为它在kdb中是常规的,并且一些构建的函数使用这个名称。

根据我的估计,对于一个简单的散列表来说,这个表太大了。我会按照日期或月份划分,这取决于你正在运行的查询类型。

如果您的查询经常选择系统的一个子集,则必须按系统排序并添加parted属性。在每个系统中按时间桶排序需要使用asof连接,因为它使用二进制搜索。

下面的代码将这样做,但由于您的文件已经用sym分隔,您应该能够跳过sym排序。

/ to sort a table in memory and apply parted attribute
update `p#sym from `sym`time xasc data 
/ to sort a table on disk and apply parted attribute
sym`time xasc `:path/to/partition
@[`:path/to/partition;`sym;`p#]

如果您的查询更适合于在所有符号中选择特定的时间窗口,那么您可能最好仅按时间桶排序,并对该列应用已排序的属性。

另外,你可能想考虑使用。q来流式传输csv文件。fs or . q。FSN减少任何单个负载的内存使用。这将允许您使用多线程或其他进程来加载具有相同内存开销的数据。

最新更新