在客户端应用程序中迭代kdb分区表的正确方法是什么?

时间:2013-06-07 19:15:06

标签: kdb

我想在R程序中处理kdb表的所有行(我使用qserver.R)。执行此操作的一种方法是初始化内存处理程序,然后在其中一个时间遍历所有行,如here所述:

t: select from mytable where ts>12:30:00,ts<15:00:00,price,msg="A"
t[0]
t[1]
t[2]
...

我想尽可能快地限制R中的客户端/服务器调用次数。 如何为每次调用获取多行?

3 个答案:

答案 0 :(得分:1)

  1. 根据您之前的问题,我认为这是一个单独的系统,那么您从kdb获得的好处是什么?为什么不在R中完全工作并直接使用平面内存映射文件?避免不必要的复杂性和开销。如果你想做的就是通过R流式传输数据,这应该很简单。

  2. 而不是“ts&gt; 12:30:00,ts&lt; 15:00:00”使用“ts(12:30:00; 15:00 00:00)”它更快。

  3. 您处理的块的大小越大,它就越有效。 100似乎很小。

  4. 此致 瑞恩汉密尔顿

答案 1 :(得分:1)

注意:我在下面的回答假定mytable是分区数据库,但您现在在内存中有t

使用cut的其他选项(根据您之前的帖子使用1,000,000的“块”)

  (`int$1e6) cut t

现在您有一个所需大小的表“块”列表,您可以相应地使用它。

我经常将此用于某些功能(特别是与peach组合使用)。

我发现有用的模式是:

 f:`function that does something useful on chunks`
 fa:`function that reaggregates up to final results`
 r:fa raze f peach (`int$`size`)cut t

如果您t非常大(垂直/水平),您可能希望出于内存原因直接在表上避免使用cut,而是可以cut列出将表格的索引转换为适当的大小,然后将索引提供给f,并将索引添加到t并抓住您想要的内容。

下面快速比较两种方法(注意f这里没有意义,只是为了证明cutt与指数的关系

   q)t:flip (`$"c",/:string til 100)!{(`int$1e7)?100} each til 100
   q)\ts a:raze {select c1,c99 from x}each 1000 cut t
   3827 4108103072j
   q)\ts b:raze {select c1,c99 from t[x]}each 1000 cut til count t
   3057 217623200j
   q)4108103072j%217623200j
   18.87714
   q)a~b
   1b

答案 2 :(得分:0)

排序,每次返回100行:

\l /data/mydb
t: select from mytable where ts>12:30:00,ts<15:00:00,price,msg="A"
select [0 100] from t
select [100 100] from t
select [200 100] from t
..