我有一个非常大的结果集要处理,所以我使用chunk()
方法来减少作业的内存占用。但是,我只想处理一定数量的总结果,以防止作业运行时间过长。
目前我正在这样做,但它似乎不是一个优雅的解决方案:
$count = 0;
$max = 1000000;
$lists = Lists::whereReady(true);
$lists->chunk(1000, function (Collection $lists) use (&$count, $max) {
if ($count >= $max)
return;
foreach ($lists as $list) {
if ($count >= $max)
break;
$count++;
// ...do stuff
}
});
有没有更干净的方法来做到这一点?
1条答案
按热度按时间ukxgm1gy1#
目前为止我不这么认为
已经有一些问题和pull请求提交,以使chunk尊重先前设置的跳过/限制,但Taylor已经关闭了它们,因为chunk会覆盖这些行为。
目前在laravel/internals repo中有一个open issue,他说他会再看一看,但我不认为它在优先级列表上很高。我怀疑这是他会做的事情,但现在可能更容易接受另一个拉取请求。
你的解决方案看起来不错,除了一件事。
chunk()
最终将阅读整个表,除非您从闭包返回false
。目前,您只是返回null
,所以即使您的“max”设置为1000000,它仍然会读取整个表。如果你在$count >= $max
的时候从你的闭包中return false
,chunk()
将停止查询数据库。它将导致chunk()
本身返回false,但是您的示例代码并不关心chunk()
的返回,所以这是可以的。另一种选择,假设你使用的是顺序id,是获取结尾
id
,然后在分块查询中添加一个where子句,以获取所有id
小于maxid
的记录。所以,类似于:代码稍微干净一点,但它仍然是一个黑客,需要一个额外的查询(以获得最大ID)。