关于Laravel Eloquent查询和急切加载,哪些查询最有效?它会产生差异吗?
$data = Model::with('relationship')
->with('relationship.content')
->with('meta')
->with('meta.meta_type')
->first
而不是:
$data = Model::with('relationship', 'relationship.content', 'meta', 'meta.meta_type')
->first;
答案 0 :(得分:1)
不,它没有任何区别。
with()
方法接受单个关系或关系。
你做的两件事情都是一样的。
以下是它在幕后的工作原理:
/**
* Begin querying a model with eager loading.
*
* @param array|string $relations
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function with($relations)
{
return (new static)->newQuery()->with(
is_string($relations) ? func_get_args() : $relations
);
}
答案 1 :(得分:1)
是的区别。这是你想到的差异吗?
答案:否。
对with()
的所有调用都将合并为一组预先加载,在调用first()
时完成查询时将对其进行解析和查询。两个代码示例都将转换为相同的一组预先加载,并且生成的模型应该是相同的。
答案:是的,小的。
性能差异非常小,并且被许多人认为是微优化(意味着如果您在大规模工作,它只值得优化)。
每次调用with()
都会确定您传递的值的类型(一个或多个字符串或数组),验证并解析关系,包括查找任何嵌套,然后将结果合并到任何以前with()
次来电的现有关系。
如果您对编写最佳代码感兴趣,可以采取的第一个也是最大的步骤是仅拨打with()
一次:
$data = Model::with('relationship', 'relationship.content', 'meta', 'meta.meta_type')
->first();
如果提供给调用的值包含一个或多个字符串,则调用PHP的func_get_args()
。如果传递数组,则直接使用该数组。这是我们可以进行的下一个优化:使用数组。
$data = Model::with(['relationship', 'relationship.content', 'meta', 'meta.meta_type'])
->first();
最后,当您将嵌套关系传递给Laravel时,两个关系都将包含在预先加载中。同时包含parent
和parent.child
关系是多余的。
您的通话 - 功能完全相同 - 可以简化为:
$data = Model::with(['relationship.content', 'meta.meta_type'])
->first();