Laravel块并删除 [英] Laravel chunk and delete

查看:68
本文介绍了Laravel块并删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有很多要从数据库中删除的项目(1M +),我派出了一个后台作业来解决这个问题,因此用户不必等待它完成就可以继续进行无论他/她在做什么,问题是,删除项目时应用程序变得无响应,所以我认为我将逐块处理项目并睡眠几秒钟然后继续。

I have a large number of items (1M+) that i want to delete from a database, i fork a background job to take care of that, so that the user won't have to wait for it to finish to carry on whatever he/she was doing, the problem is, the app becomes unresponsive while the items are being deleted, so i thought that i would process the items chunk by chunk and sleep for a couple of seconds then carry on.

以下是处理删除的代码:

Here is the code that handles the delete:

// 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秒钟,重复该过程,直到删除所有项目为止。

Expected result: the posts are chunked and each chunk is processed, then idle for 2 seconds, repeat that until all the items are deleted.

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

Actual result: a random number of items is deleted once, then the process ends. no errors no indicators, no clue ?

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

is there a better way to implement this?

推荐答案

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

There is nothing Laravel specific about the way you'd handle this. It sounds like your database server needs review or optimization if a delete query in a job is freezing the rest of the UI.

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

Retrieving each model and running a delete query individually definitely isn't a good way to optimize this as you'd be executing millions of queries. You could use a while loop with a delete limit if you wish to try to limit the load per second in your application instead of optimizing your database server to handle this query:

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

这篇关于Laravel块并删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆