skip to Main Content

I need to update every row of my table associated with the model MyModel. Each update requires PHP code to be executed. In my case it is not a problem, but I wondered how to do this more efficiently?

MyModel::chunk(1000, function (Collection $collection) {
     foreach ($collection as $model) {
         $pascalCaseModelName = $model->modelName;
         $myModel->modelAlias = Str::snake($pascalCaseModelName);
         $myModel->save();
     }
});

Right now I save each model after I processed it. That means a database query is executed for every model. I wonder if it is possible to save a whole chunk with on statement that triggers one database query instead.

The only solution I could find is the saveMany method. But this can only be applied to relations.

2

Answers


  1. Chosen as BEST ANSWER

    Based on Zacharias's suggestion, I managed to solve the problem. But I used the upsert method instead of update.

    MyModel::chunk(1000, function (Collection $collection) {
     $updates = [];
    
     foreach ($collection as $model) {
         $pascalCaseModelName = $model->modelName;
         $updates[] = [
            'id' => $model->id,
            'model_alias' => Str::snake($pascalCaseModelName),
         ];
     }
    
     if (!empty($updates)) {
         DB::table('my_models')->upsert(
             $updates,
             ['id'], 
             ['model_alias']
         );
     }
    

    });

    While update can update multiple records, it can't insert different values for each model. upsert can. See https://laravel.com/docs/10.x/queries#upserts


  2. Have you tried this?

    MyModel::chunk(1000, function (Collection $collection) {
         $updates = [];
    
         foreach ($collection as $model) {
             $pascalCaseModelName = $model->modelName;
             $updates[] = [
                'id' => $model->id,
                'model_alias' => Str::snake($pascalCaseModelName),
             ];
         }
    
         if (!empty($updates)) {
             DB::table('my_models')->update($updates, 'id');
         }
    });
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search