Laravel模型属于关系加载问题

问题描述 投票:0回答:1

我有两个模型,Box和BoxLocations。 BoxhasManyBoxLocations关系,BoxLocationsbelongsToBox关系。

BoxLocations还有一个附加到模型的属性,该属性需要来自Box关系的单条信息。

我注意到,在调用Box::with(['BoxLocations']->)all();时,我看到BoxLocations模型正在重新加载Box关系。这发生在每个BoxLocation(50多次)

laravel是否跟踪Box已从最初的Box::with(['BoxLocations']->)all();请求加载,然后将其传递给BelongsTo关系?

我正在尝试优化一个Web系统,并且当加载了take属性时(每次加载时都需要它),它会导致已经加载的相同Box模型的50多次点击到数据库。

如果laravel没有这样做 - 是否有更好的方法来实现上述目标?

laravel laravel-5.5
1个回答
0
投票

当你使用eager loading方法时,Laravel使用with()

当访问Eloquent关系作为属性时,关系数据是“延迟加载”。这意味着在您首次访问该属性之前,实际上不会加载关系数据。但是,Eloquent可以在您查询父模型时“急切加载”关系。急切加载缓解了N + 1查询问题。

所以,如果你这样做:

$boxes = Box::with('BoxLocations')->get();

它会加载关系,但让我们说你这样做:

$boxes = Box::all();

foreach($boxes as $box)
{
  echo box->boxlocation->name;
}

如果你有50个Box,这个循环将运行51个查询。

但是当你使用with方法并急切加载关系时,这个循环只会运行2个查询。

您也可以使用Lazy Eager Loading并决定何时加载关系

© www.soinside.com 2019 - 2024. All rights reserved.