【问题标题】:UpdateExistingPivot for multiple ids in loop = n+1 problem. Is there another way?UpdateExistingPivot for multiple ids in loop = n+1 问题。还有其他方法吗?
【发布时间】:2019-03-11 12:03:52
【问题描述】:

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

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

  1. 位置模型
  2. 供应商型号
  3. 用户模型
  4. Contactable(自定义枢轴模型 - 仍在充实这一点)

用户可以被标记为位置和供应商的联系人(也称为联系人)。 我需要在分离联系人时分离它们(我需要记录用户曾经是某个位置或供应商的联系人的事实)所以我不想分离它们,我需要将它们标记为非活动状态。 我将把这个场景的范围限制在 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+ 个更新操作来处理真正应该是一个查询的内容。 DB 位于不同的服务器上,因此额外的几毫秒加起来很快......

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

(为清晰起见已更新)

【问题讨论】:

标签: php laravel eloquent laravel-5.3


【解决方案1】:

使用raw query 代替relationship

我不完全了解您要停用哪些行。
因此,让我们认为您想要为特定的user 停用可联系。
如果不是,请将其更改为 where()

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

这只会执行一个查询。

【讨论】:

  • 感谢您的想法 - 使用原始查询可能是解决我的问题的最实用方法。不幸的是,您发布的查询并没有真正解决我关于多态关系的 n+1 问题。我需要传入一个 ID 数组(在我的例子中,一个位置 ID 数组)。更像是:DB::table('contactable')->where('contactable_type', 'App\Models\Location')->whereIn('contactable_ID', $arryaOfLocation_IDs)->update(['active' => 0]);真正喜欢的是一种雄辩的方式。
猜你喜欢
  • 2023-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多