我有大约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减少任何单个负载的内存使用。这将允许您使用多线程或其他进程来加载具有相同内存开销的数据。