Laravel块并删除 [英] Laravel chunk and delete
问题描述
我有很多要从数据库中删除的项目(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屋!