我有一个“检索”(在这种情况下只是创建)一个表并将其存储在新分区中的函数
npertable:100000;
dbname:`:partdb;
newpart:{[date]
firstofmonth:"d"$"m"$date;
table:([]date:npertable?firstofmonth+til 25;acc:npertable?`C123`C132`C321`C121`C131;c:npertable?til 100);
table:`date`acc xasc table;
partname:`$(("/" sv (string dbname;string "m"$date;enlist "t")),enlist "/");
partname set .Q.en[dbname;table];
};
假设在函数内部创建table
需要“很长”的时间(例如很多行)。现在,我不能在不同的线程上使用这个方法
newpart peach 2018.03.01 2018.04.01 2018.05.01
因为
ERROR: 'noupdate: `. `sym
这并不奇怪,因为它可能无法异步更新sym文件。
有没有办法在kdb中并行存储分区?
感谢您的帮助
答案 0 :(得分:2)
另一种方法是重新修改您的功能并将其分解为更小的步骤。我首先将枚举从设置中分离到磁盘 - 这样就可以枚举所有表格'主线程中的sym列,然后将枚举数据设置为线程中的磁盘。注意 - 如果您首先并行化磁盘io,这可能会很有用。
npertable:100000;
dbname:`:partdb;
createTab:{[datep]
firstofmonth:"d"$"m"$datep;
table:([]date:npertable?firstofmonth+til 25;acc:npertable?`C123`C132`C321`C121`C131;c:npertable?til 100);
delete date from `date`acc xasc table
};
createPath:{[datep]
.Q.dd[dbname;(datep;`t;`)]
};
enumTab:{[t]
.Q.en[dbname;t]
};
setInParallel:{[datep]
enummedTabs:{enumTab createTab x} each datep;
paths:createPath each datep;
.[set;] peach flip (paths;enummedTabs)
};
现在,您可以针对日期列表运行setInParallel
bash> q code.q -s 5
q)setInParallel .z.d-til 5
`:partdb/2018.04.25/t/`:partdb/2018.04.24/t/`:partdb/2018.04.23/t/`..
需要注意的一些注意事项:
将表格设置为日期分区时,您不需要日期列。你当然可以拥有它,但当q映射到日期目录时它就变成了虚拟日期列,所以不需要它。因此,为什么我在创建时删除日期列。
.Q.dd
是一个非常有用的创建路径的函数(比构建字符串更容易)。请注意我如何从根hdb,日期参数,表名和前导`创建路径(在创建路径时表示前导/(即dir))
我从createTab
函数中获取的newpart
函数。您将输入的日期转换为一个月,然后返回到日期以获取该月的第一个日期。这可能是你正在寻找的,但只是因为你知道你永远不能设置除了本月的第一天之外的日期,即使你输入的参数是2018.01.02例如。
HTH, 肖恩
答案 1 :(得分:1)
你可以做到这一点,但它依赖于你在减记之前知道完整的可能符号世界。如果看起来像是某种帐户ID,那么在我保存之前你可能知道所有可能的值。在这种情况下,您可以先在主线程中创建sym向量,然后将写下来,使用$运算符执行枚举,该运算符不会更新全局变量。例如:
User.findOne({
where: { id: req.params.id },
attributes: ['id', 'user_name'],
include: [
{ model: Post,
attributes: ['id', 'created_at'],
include: {
model: PostTitles,
attributes: ['title_id',[Sequelize.literal('COUNT(DISTINCT(title_id))'), 'totalcount']]
}
}
]
})
请注意,在这种情况下,要枚举的列名称是硬编码的 - 在更灵活的实现中,您可以使用npertable:100000;
dbname:`:partdb;
sym:`C123`C132`C321`C121`C131; //create sym vector
(` sv dbname,`sym) set sym; //save sym vector in db
newpart:{[date]
firstofmonth:"d"$"m"$date;
table:([]date:npertable?firstofmonth+til 25;acc:npertable?`C123`C132`C321`C121`C131;c:npertable?til 100);
table:`date`acc xasc table;
partname:`$(("/" sv (string dbname;string "m"$date;enlist "t")),enlist "/");
table:@[table;`acc;`sym$]; //enumerate acc column with hardcoded column name
partname set table; //table already enumerated, don't use .Q.en
};
newpart peach 2018.03.01 2018.04.01 2018.05.01
的某些修改来标识需要枚举的列,并自动为所有必需的列执行此操作。 / p>
当然,如果在您的真实.Q.en
函数中,有可能将新的值添加到newpart
字段,则会产生更大的问题。理想情况下,您可能希望在执行acc
之前了解主线程中的任何新值,因此您可以向peach
向量添加任何新值。
答案 2 :(得分:1)
有可能(尽管我没有经过彻底的测试)设置一个单独的编写程序来处理写作,然后你将数据发送到编写器,编写器将依次进行枚举和编写。有点像:
{neg[h](`runThisFunc;onThisData);(neg h)[]} peach 1 2
我相信需要冲洗。较新版本的kdb可以允许通过IPC发送大量数据,因此该部分不应成为问题。
我再也没有在制作环境中做过这件事,但从理论上讲,我无法想到你为什么不能这样做。