php - 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 秒,重复此操作直到所有项目都被删除。
实际结果:随机删除一次,然后流程结束。没有错误没有指标,没有线索?
有没有更好的方法来实现这一点?
解决方案
Laravel 没有具体说明您处理此问题的方式。如果作业中的删除查询冻结了 UI 的其余部分,听起来您的数据库服务器需要审查或优化。
检索每个模型并单独运行删除查询绝对不是优化它的好方法,因为您将执行数百万个查询。如果您希望尝试限制应用程序中的每秒负载,而不是优化数据库服务器来处理此查询,则可以使用带有删除限制的 while 循环:
do {
$deleted = Post::where('arch_id', $posts_archive->id)->limit(1000)->delete();
sleep(2);
} while ($deleted > 0);
推荐阅读
- docker - 在 docker 中配置 cassandra.yaml 以进行密码验证
- opencv - 初始化一个4通道矩阵opencv
- python - Matplotlib - 创建滚动二维直方图
- java - 如何编写规则来匹配两个数组?
- google-api - 将阿拉伯名字音译为拉丁字符
- bxslider - goToSlide 与 bxSlider 不工作
- neo4j - Neo4j Cypher 使用 APOC apoc.index.relationships 更改过滤操作
- reactjs - 在 React js 中插入 google adwords 标签
- bash - Bash 测试运算符 [[ ... -eq ... ]] 中的错误或功能?
- php - 如何在 Yii 框架中将 date 的默认值更改为 null?