我的hdb中有一个分区表,其中包含一个包含大型浮点列表的列(每个元素最多400个浮点数)。例如,每个元素看起来像
(100.0 1.0 ...)
当尝试从行数特别多的日子中选择此列时,我收到错误消息
'./2015.02.07/table/column# Cannot allocate memory
同样的错误来自如下查询:
select column[;0] from table where date=2015.02.07
即使在行数较少的日子,此查询也会返回列中每个元素的第一个值。
有没有办法在select中流式传输此列,以减少将整个列保留在内存中一天的内存要求?
修改
。大天的.Q.ind失败并出现同样的错误。
即如果我可以使用2015.02.01而不是2015.02.02:
.Q.ind[select from table where date=2015.02.01;enlist 1]
很好,但
.Q.ind[select from table where date=2015.02.02;enlist 1]
失败
{0!$[#.Q.pm;p3;(?).]@[x;0;p1[;y;z]]}
'./2015.02.10/table/column2#: Cannot allocate memory
@
.[?]
(+`time`sym`column1`column2!`:./2015.02.02/table;();0b;())
我应该注意到我使用的是免费的32位版本
答案 0 :(得分:1)
嵌套列以常规方式查询很困难,因为#
文件也需要加载到内存中(即使使用[;0]
)
您最好的选择是选择映射日期分区,然后在该块中选择块,例如一次一百万行(或者根据嵌套浮动的大小,任何合理的行)。
如果可以牺牲一些十进制精度,也许还可以考虑32位浮点数。
修改强>
所以在评论之后我想最好的方法是使用.Q.ind
答案 1 :(得分:1)
我认为这只是免费32位内存限制的组合,事实上你的行数可能很大,并且(不可避免地)某些的事实必须完全被拉到内存中从列中检索数据,无论是完全引入的列本身(在非嵌套情况下)还是完全拉入的嵌套索引列。
另一件需要考虑的事情是kdb使用二次幂(伙伴)内存分配。即使今天的表只包含比昨天多一行,每列的内存需求可能会翻倍。举一个简单的例子:
在免费的32位版本(windows)中你可以创建这么多的浮点数,它只使用~1.07g的内存
q)\ts 134217726?1.0
3093 1073741952
但是,尝试生成一个额外的浮点数并达到内存限制
q)\ts 134217727?1.0
wsfull
因此,如果您接近可分配权力2的边界,即使一天和下一天之间的差异中的少量行也会非常重要。
- 免责声明 - 以下是hacky,仅用于调试!
您实际上可以手动尝试从嵌套列表中访问数据,但无论如何您仍可能遇到内存问题。
创建嵌套表并展开
q)tab:([] col1:(101 102 103f;104 105f;106 107 108 109 110f;111 112f))
q)tab
col1
--------------------
101 102 103f
104 105f
106 107 108 109 110f
111 112f
q)
q)`:test/ set tab
`:test/
您可以尝试从嵌套索引文件
中读取索引q)2_first (enlist "j";enlist 8)1:`:test/col1
3 5 10 12
因此,拆分完整浮动列表(col1#文件)的索引是索引3,索引5,10等等
说我想要前3行
q)myrows:3#2_first (enlist "j";enlist 8)1:`:test/col1
q)myrows
3 5 10
然后我知道我需要col1#文件中的前10个浮点数,需要将它们拆分为索引3和5.然后我可以读取col1 #file 部分并正确拆分< / p>
q)(0,-1_myrows) cut raze (enlist "f";enlist 8)1:(`$":test/col1#";0;8*last myrows)
101 102 103f
104 105f
106 107 108 109 110f
但这正是KDB无论如何都要做的事情,所以我怀疑你甚至在第一时间阅读嵌套索引文件时仍然会遇到麻烦。
检查此调试/黑客,看看你是否可以部分阅读。但显然它不是一个长期的解决方案!
答案 2 :(得分:0)
仅花2美分,我遇到了一个类似的错误,但有一个64位实例。
我怀疑内存需要运行近一年才能进行碎片整理。
启动实例可以解决该问题,并释放了大量的虚拟内存