UpdateExistingPivot中的多个ID处于循环= n + 1问题。还有另一种方法吗?

时间:2018-10-06 00:50:01

标签: php laravel eloquent laravel-5.3

another very similar issue的答案非常有帮助(我目前正在使用),但会导致n + 1查询问题。

我将概述用例。多态多对多关系 我有:

  1. 位置模型
  2. 供应商模型
  3. 用户模型
  4. 可联系(自定义枢轴模型-仍然充实)

可以将用户标记为位置和供应商的联系人(也称为可联系对象)。 解除可联系对象的关联时,我需要(我需要记录一个用户曾经是某个位置或供应商的联系人的事实),所以我不想分离它们,我需要将它们标记为不活动。 我将这种情况的范围限制为contactables表中的以下字段:

  1. 活动
  2. user_ID
  3. contactable_type
  4. contactable_ID

所以我正在执行:

    $collectionOfLocationIds = $contactDetails->locations()->getRelatedIds(); //changed to 'allRelatedIds()' in 5.4+

    foreach ($collectionOfLocationIds as $locationID)
     {
       $contactDetails->locations()->updateExistingPivot($locationID, ['active' => 0]);
     }

这对于我的大多数供应商来说都运行得很好,但是有些供应商拥有5k +个位置,因此我要对实际上应该是一个查询执行5k +个更新操作。数据库位于另一台服务器上,因此,额外的几毫秒很快就累了……

我尝试将ID数组传递给updateExistingPivot函数(it says it will take a mixed type for the id parameter),它不会产生错误,但似乎只更新了数组中的第一个ID。我不确定这是否是新错误,@ Wallace Maxters提到他可以在4.2中传递数组,而我仍在5.3中工作,但是我想知道是否还有其他人遇到了这个问题。 / p>

(为清楚起见已更新)

1 个答案:

答案 0 :(得分:1)

使用raw query代替relationship

我不确定您要停用哪些行。
因此,让我们以为您想使user处于非活动状态可联系。
如果不是,请将其更改为任何where()

DB::table('contactable')->where('user_id', $user_id)
    ->update(['active' => 0]);

这只会执行一个查询。