我有一个postgres数据库,其中包含一个表,其中包含我想以伪随机间隔查找的行。有些我想每小时看一次,有的每天一次,有的每周一次。我希望查找在其时间窗口内以伪随机间隔进行。因此,我每天要做的一次查看应该在每次运行的不同时间进行。
我怀疑有一种更简单的方法可以做到这一点,但这是我的粗略计划: 为每个查找项设置一个设置列。脚本启动时,会随机化每次查找的纪元时间,并将其设置在设置列中,以确定下次查找的时间。然后我运行一个等待1的连续循环,以查看纪元时间是否与任何请求的查找匹配。在运行查找时,它会在下次查找时重新计算。
我的问题: 即使在设计阶段,这看起来就像是一个胶带和麻线。什么是正确的方法?
如果偶然,我的想法是正确的方法,我的想法是重复循环等待1正确的方式去?如果我有两次背靠背查找,我有可能错过一次,但我可以忍受。
感谢您的帮助!
答案 0 :(得分:5)
为NextCheckTime的表添加一列。您可以使用时间戳或仅使用原始纪元时间的整数。在NextCheckTime上添加(非唯一)索引。
当您向数据库添加行时,通过获取当前时间,添加基本间隔,添加/减去随机因子(可能是基本间隔的25%,或适合您的情况的任何内容)来填充NextCheckTime。例如:
my $interval = 3600; # 1 hour in seconds
my $next_check = time + int($interval * (0.75 + rand 0.5));
然后在你的循环中,只需SELECT * FROM table ORDER BY NextCheckTime LIMIT 1
。然后睡觉,直到返回的NextCheckTime(假设它已经不在过去),执行查找,并如上所述更新NextCheckTime。
如果您需要处理其他进程新添加的行,则可能会限制睡眠。如果NextCheckTime将来超过10分钟,则休眠10分钟并重复SELECT以查看是否添加了任何新行。 (同样,确切的限制取决于您的情况。)
答案 1 :(得分:0)
您的数据集有多大?如果它只是几千行而不是随机化整个列表并抓住前x行是可以的。随着您的集合规模的增长,这变得越来越不可扩展。性能以非线性速率下降。但是如果你最多只需要每小时运行一次,那么只要它不会杀死同一个盒子上的其他进程只需要一两分钟就没什么大不了的。
如果您有无间隙序列,无论是从头开始还是添加,那么您可以使用索引:
$i=random(0,sizeofset-1);
select * From table where seqid=$i;
并获得数百万行的良好可扩展性。