内存不足错误,尝试在紧急加载时获取 1 条雄辩记录属于许多



我有这个查询:

Order::find('1234')->refunds()->with('orderItems')->get()

这会导致内存不足错误耗尽 256 MB 来获取一行,而加载的items也只有一行。

如果我尝试这个,我没有问题:

Order::find('1234')->refunds->first()->orderItems

只有当我急切加载时。

我的枢轴定义:

public function items(): BelongsToMany
{
return $this->belongsToMany(OrderItem::class)
->using(OrderItemRefund::class)
->withPivot([
'amount',
]);
}

当我查看它在跟踪中失败的查询时,我看到以下内容:

SELECT
`order_items`.*,
`order_item_refund`.`refund_id` AS `pivot_refund_id`,
`order_item_refund`.`order_item_id` AS `pivot_order_item_id`,
`order_item_refund`.`amount` AS `pivot_amount`
FROM
`order_items`
INNER JOIN `order_item_refund` ON `order_items`.`id` = `order_item_refund`.`order_item_id` 
WHERE
`order_item_refund`.`refund_id` IN ( 0 ) 
AND `order_items`.`deleted_at` IS NULL

关键问题似乎是 Eloquent 如何在内部构建部件refund_id IN ( 0 ),而它没有为数据透视表添加相关的refund_id值。如果我在数据库上将其作为原始查询运行,它将返回连接满足的所有记录,而不按refund_id过滤,这只会产生一条记录。

选中时,透视查询的绑定为空:

{
bindings: [], 
connectionName: mysql, 
executionTimeMs: 8663.32
}

但是,Eloquent 查询的所有绑定在此之前都会执行,直到透视具有预期值。

我还进一步发现,这会影响所有使用BelongsToMany模型中的所有关系。代码在升级到 Laravel 8 后才开始运行(特别是我们在 v8.83.14 上)。

我尝试将 Laravel 和 Doctrine 降级到早期的次要版本,同时仍然保留在 v8 上,但这没有帮助。

在 Laravel 6 中,主键现在被转换为整数,除非明确设置为字符串。

https://laravel.com/docs/6.x/upgrade#eloquent-primary-key-type

发生这种情况的原因是因为我们从 Laravel 5.4 升级到 Laravel 8 并且具有基于字符串的主键。

在相关模型上设置以下内容解决了该问题:

protected $keyType = 'string';

最新更新