【问题标题】:memory size exhausted with laravel soft delete actionlaravel 软删除操作耗尽内存大小
【发布时间】:2019-03-17 17:40:33
【问题描述】:

在 Laravel 5.6 中,当我尝试使用我的函数软删除具有大记录的表中的所有数据时:

public function clearActivityLog() {
    $activities = Activity::all();

    foreach ($activities as $activity) {
        $activity->delete();
    }

    return redirect('admin/activity')
        ->with('success', trans('backend/main.logs.activity.messages.logClearedSuccessfuly'));
}

我收到此错误:

134217728字节的允许内存大小用尽(尝试分配20480字节)

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    Jerodev 的答案在这种情况下是一个很好的答案。

    在某些情况下,您无法进行批量更新(例如,如果您需要对每个项目进行处理,或者如果您需要触发 Eloquent 事件)。在这些情况下,您可以使用chunk 避免内存不足:

    Activity::chunk(100, function($activities) {
        foreach ($activities as $activity) {
            $activity->delete();
        }
    });
    

    这样做一次只会将 100 个(您可以在此处选择任何数字)提取到内存中(而不是 Activity::all(),它将每个活动一次加载到内存中;如果这是数百万行,您可以轻松理解为什么会出现内存错误)。

    【讨论】:

    • 我喜欢这个,因为如果由于某种原因软删除最终变成了硬删除,这将继续有效。
    • Activity::query()->delete(); 也是如此,它需要一个数据库查询而不是数据库中的每个活动一个。
    【解决方案2】:

    如果有很多活动,这可能会产生大量查询。这可以通过一个查询来完成,如下所示:

    Activity::query()->update('deleted_at', now());
    

    softdeletes 使用deleted_at 列来检查该行是否被删除。因此,为所有行手动设置列会产生相同的效果。

    【讨论】:

    • 好答案,但不应静态调用非静态方法 update()
    • 已通过将query() 放在首位进行修复。
    【解决方案3】:

    一个更“雄辩”的解决方案(并且可能更适合未来)

    Activity::query()->delete();
    

    这会为 Activity 模型检索一个没有任何限制的查询构建器,因此 delete() 将应用于所有模型。它不会加载所有活动,而是在一次调用中删除它们。它还表明不了解软删除的内部工作,这对于向前兼容是更可取的。

    【讨论】:

    • 我在发布我的问题之前尝试了这个答案,它只是删除所有记录而不是软删除。
    • 请仔细检查这是否属实,如果是这样,请在 github 上向 Laravel 团队报告一个错误
    • 你也可以工作,但我不知道为什么我会遇到这样的问题!无论如何谢谢大家。
    猜你喜欢
    • 1970-01-01
    • 2018-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    • 2016-08-31
    • 1970-01-01
    相关资源
    最近更新 更多