0
votes

In Laravel 5.6 when i try to Soft Delete all data in table with large records with my function:

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'));
}

I get this error:

Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes)

3

3 Answers

3
votes

If there are lots of activities this could potentially generate an enormous amount of queries. This could be done with one query like so:

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

softdeletes uses the deleted_at column to check if the row is deleted. So setting the column manually for all rows gives the same effect.

1
votes

Jerodev's answer is a good one in this scenario.

In some cases, you can't do a bulk update (like if you need to do processing on each item, or if you need Eloquent events to fire). In those cases, you can avoid running out of memory by using chunk:

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

Doing this fetches only 100 (you can pick any number here) at a time into memory (versus Activity::all(), which loads every single activity into memory at once; if that's millions of rows, you can easily understand why you'd get a memory error).

1
votes

A more "eloquent" solution (and probably more future proof)

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

This retrieves a query builder for the Activity model with no restrictions so the delete() will apply to all. It does not load all the Activities up but instead deletes them in one call. It also shows no knowledge of the inner working of soft deletes which is preferable for forward compatibility.