
最好使用 chunkbyid 而不是 chunk 以避免批量更新时丢失行。使用 chunk 可以在更新行后移动后续查询的偏移量,从而导致跳过未处理的行。
例如:
post::where('processed', 0)->chunk(100, function($posts) {
foreach($posts as $post) {
$post->processed = 1;
$post->save();
}
});
上面的代码生成以下查询。
select * from `posts` where `processed` = 0 limit 100 offset 0 select * from `posts` where `processed` = 0 limit 100 offset 100 ...
第一个块更新 100 行。第二个查询没有意识到这一点,因此跳过 100 个未处理的行,因为它仍然使用偏移量。
以上由
详细解释
太阮雄
当尝试使用 laravel 的 chunk() 方法处理有限数量的行时,我们可能期望以下代码以 2 为一组仅处理 5 个用户:
本系统经过多次升级改造,系统内核经过多次优化组合,已经具备相对比较方便快捷的个性化定制的特性,用户部署完毕以后,按照自己的运营要求,可实现快速定制会费管理,支持在线缴费和退费功能财富中心,管理会员的诚信度数据单客户多用户登录管理全部信息支持审批和排名不同的会员级别有不同的信息发布权限企业站单独生成,企业自主决定更新企业站信息留言、询价、报价统一管理,分系统查看分类信息参数化管理,支持多样分类信息,
0
$query = \app\models\user::query()->take(5);
$query->chunk(2, function ($users) {
// process users
});
但是,这将处理数据库中的所有用户,一次两个。发生这种情况是因为 laravel 的 chunk() 方法忽略了应用于查询的 take() 限制,导致所有行都以块的形式处理。
为了确保只在块中处理有限数量的行(例如 5 个用户),我们可以实现一个自定义索引计数器,该计数器将在达到指定限制后中断分块循环。以下代码实现了这一点:
class UserProcessor
{
private int $index = 0;
private int $limit = 5;
public function process()
{
$query = \App\Models\User::query();
$query->chunk(2, function ($users) {
foreach ($users as $user) {
$this->index++;
// Process each user here
// Example: $user->processData();
if ($this->index >= $this->limit) {
// Stop processing after reaching the limit
return false; // This will stop chunking
}
}
});
}
}
注意
$index 和 $limit 是类的属性,而不是通过 use($index, $limit) 传递给闭包的方法变量。这是因为通过 use() 传递的变量会按值复制到闭包对象中。因此,闭包内的任何修改都不会影响原始值,这就是为什么它们必须是类属性才能正确更新和跟踪迭代之间的更改。
以上就是优化 Laravel 查询:分块数据的正确方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号