首页 > 解决方案 > Laravel 分块和删除

问题描述

我有大量项目(1M+)要从数据库中删除,我派生了一个后台作业来处理它,这样用户就不必等待它完成来继续他/她在做,问题是,当项目被删除时,应用程序变得无响应,所以我想我会逐块处理项目并休眠几秒钟然后继续。

这是处理删除的代码:

// laravel job class
// ...
public function handle()
{
    $posts_archive = PostArchive::find(1); // just for the purpose of testing ;)
    Post::where('arch_id', $posts_archive->id)->chunk(1000, function ($posts) {
        //go through the collection and delete every post.
        foreach($posts as $post) {
            $post->delete();
        }
        // throttle
        sleep(2);
    });
}

预期结果:帖子被分块并处理每个块,然后空闲 2 秒,重复此操作直到所有项目都被删除。

实际结果:随机删除一次,然后流程结束。没有错误没有指标,没有线索?

有没有更好的方法来实现这一点?

标签: phplaraveleloquentjobs

解决方案


Laravel 没有具体说明您处理此问题的方式。如果作业中的删除查询冻结了 UI 的其余部分,听起来您的数据库服务器需要审查或优化。

检索每个模型并单独运行删除查询绝对不是优化它的好方法,因为您将执行数百万个查询。如果您希望尝试限制应用程序中的每秒负载,而不是优化数据库服务器来处理此查询,则可以使用带有删除限制的 while 循环:

do {
    $deleted = Post::where('arch_id', $posts_archive->id)->limit(1000)->delete();
    sleep(2);
} while ($deleted > 0);

推荐阅读