Kdb 如何远程更新本地表?

Kdb 如何远程更新本地表?,kdb,Kdb,我在远程服务器上有一个很大的表,其中有数百万行未知的数据。我希望能够一次批量获取100000行数据,用这些获取的行更新本地表,并完成此操作,直到所有行都被获取。有没有办法远程更新本地表 目前,我在服务器上有一个名为t的虚拟表以及以下变量 t:([]sym:1000000?`A`B`Ab`Ba`C`D`Cd`Dc;id:1+til 1000000) selector:select from t where sym like "A*" counter:count selector divy:coun

我在远程服务器上有一个很大的表,其中有数百万行未知的数据。我希望能够一次批量获取100000行数据,用这些获取的行更新本地表,并完成此操作,直到所有行都被获取。有没有办法远程更新本地表

目前,我在服务器上有一个名为t的虚拟表以及以下变量

t:([]sym:1000000?`A`B`Ab`Ba`C`D`Cd`Dc;id:1+til 1000000)
selector:select from t where sym like "A*"
counter:count selector
divy:counter%100000
divyUP:ceiling divy
客户端上的以下函数以及变量索引设置为0和normTable,这是远程表的副本

index:0
normTable:h"0#t"

batches:{[idx;divy;anty;seltr]
    if[not idx=divy;
    batch:select[(anty;100000)] from seltr;
    `normTable upsert batch;
    idx+::1;
    divy:divy;
    anty+:100000;
    seltr:seltr;
    batches[idx;divy;anty;seltr]];
    idx::0}
我使用以下命令调用该函数

 batches[index;h"divyUP";0;h"selector"]
然而,这种方法的问题是,hselector同时多次获取所有数据行——对于它向上插入到本地表中的每一批100000行数据

我可以将批处理功能移动到远程服务器,但如何远程更新本地表

或者,我可以在服务器上将行分解为多个批,然后分别提取每个批。但是如果我不知道有多少行,我怎么知道需要多少变量呢?例如,以下选项可以使用,但最多只能使用前400k行

batch1:select[100000] from t where symbol like "A*"
batch2:select[100000 100000] from t where symbol like "A*"
batch3:select[200000 100000] from t where symbol like "A*"
batch4:select[300000 100000] from t where symbol like "A*"

有没有办法设置batchX变量,以便它创建一个等于divyUP计数的新变量?

我建议您在尝试连接到远程服务器时进行一些更改:

不要运行同步请求,因为这会使服务器减慢其处理速度。尝试使用发出异步请求。 不要在每次调用中专门针对正则表达式进行全表扫描以进行大量比较。在下一次调用中,大部分数据可能在缓存中可用,但仍然不能保证,这将再次影响服务器的正常操作。 不要在突发状态下发出数据请求。当最后一批数据到达时,使用计时器或进行另一个数据请求调用。 以下方法基于上述建议。它将避免扫描整个表中除索引列以外的列,索引列重量较轻,并且只有在最后一批到达时才发出下一个请求

创建批处理函数

此函数将在服务器上运行,使用索引从表中读取小批量数据,并返回所需的数据

q) batch:{[ind;s] ni:ind+s; d:select from t where i within (ind;ni), sym like "A*"; 
                  neg[.z.w](`upd;d;$[ni<count t;ni+1;0]) }
创建主函数以启动流程

最后打开连接,创建表变量并运行fetch函数

q) h:hopen `:server:port
q) t:()
q) size:100
q) fetch 0
现在,上述方法基于服务器表是静态的假设。若要实时更新,则需要根据服务器上更新表的方式进行更改


此外,还可以根据远程表上设置的属性进行其他优化,这可以提高性能。

我建议您在尝试连接到远程服务器时进行一些更改:

不要运行同步请求,因为这会使服务器减慢其处理速度。尝试使用发出异步请求。 不要在每次调用中专门针对正则表达式进行全表扫描以进行大量比较。在下一次调用中,大部分数据可能在缓存中可用,但仍然不能保证,这将再次影响服务器的正常操作。 不要在突发状态下发出数据请求。当最后一批数据到达时,使用计时器或进行另一个数据请求调用。 以下方法基于上述建议。它将避免扫描整个表中除索引列以外的列,索引列重量较轻,并且只有在最后一批到达时才发出下一个请求

创建批处理函数

此函数将在服务器上运行,使用索引从表中读取小批量数据,并返回所需的数据

q) batch:{[ind;s] ni:ind+s; d:select from t where i within (ind;ni), sym like "A*"; 
                  neg[.z.w](`upd;d;$[ni<count t;ni+1;0]) }
创建主函数以启动流程

最后打开连接,创建表变量并运行fetch函数

q) h:hopen `:server:port
q) t:()
q) size:100
q) fetch 0
现在,上述方法基于服务器表是静态的假设。若要实时更新,则需要根据服务器上更新表的方式进行更改


此外,还可以根据远程表上设置的属性进行其他优化,这可以提高性能。

如果您可以发送同步消息,则可以将其简化为:

{[h;i]`mytab upsert h({select from t where i in x};i)}[h]each 0N 100000#til h"count t"

通过使用10 0N,您可以轻松地将其更改为控制批数而不是大小,这将在10批中完成

如果您可以发送同步消息,它可以简化为:

{[h;i]`mytab upsert h({select from t where i in x};i)}[h]each 0N 100000#til h"count t"

您可以很容易地更改它来控制批次数量而不是大小,方法是使用10 0N,这将在10个批次中进行操作,而不是使用单个变量,剪切函数可以将选择的结果拆分为100000行的块。索引每个元素就是一个表

batches:100000 cut select from t where symbol like "A*"

cut函数可以将select的结果分成100000行的块,而不是单个变量。索引每个元素就是一个表

batches:100000 cut select from t where symbol like "A*"

谢谢,拉胡尔。我不太熟悉kdb中的回调
现在就开始。回调函数和main函数是否同时存在于客户端和服务器上,还是仅存在于客户端或服务器上?我提到的所有函数都将存在于客户端。回调通常是其他进程在异步调用中完成客户端请求后在客户端调用的函数实现。另一种想法是发布者在有更新时调用订阅服务器上的函数。谢谢,Rahul。我现在不太熟悉kdb中的回调。回调函数和main函数是否同时存在于客户端和服务器上,还是仅存在于客户端或服务器上?我提到的所有函数都将存在于客户端。回调通常是其他进程在异步调用中完成客户端请求后在客户端调用的函数实现。另一种想法是发布者在有更新时调用订阅服务器上的函数。