Laravel Eloquent с синтаксисом - какой из них более эффективен

Leon спросил: 28 марта 2018 в 04:49 в: mysql

Что касается 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;

2 ответа

Есть решение
Aken Roberts ответил: 28 марта 2018 в 07:51

В есть разница. О чем вы думаете?

Есть ли разница в выполняемых запросах / запросах или в возвращаемых данных?

Ответ: Нет.

Все вызовы with() будут объединены в один набор активных нагрузок, которые будут анализироваться и запрашиваться после завершения запроса после вызова first(). Оба примера кода будут превращены в один и тот же набор активных нагрузок, а полученные модели должны быть идентичны.

Есть ли разница в производительности?

Ответ: Да, a маленький.

Разница в производительности очень мала, и многие считают ее микрооптимизацией (это означает, что оптимизировать ее стоит только при работе в значительном масштабе).

Каждый вызов with() определяет тип переданного вами значения (одну или несколько строк или массив), проверяет и анализирует отношения, включая поиск любых вложенных, а затем объединяет результаты с любыми существующими отношениями из предыдущих вызовов with().

Если вы заинтересованы в написании наиболее оптимального кода, первый и самый большой шаг, который вы можете сделать, - это вызвать только with() Once:

$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();
Leon ответил: 29 марта 2018 в 08:08
Это именно тот ответ, на который я надеялся, спасибо!
Aken Roberts ответил: 30 марта 2018 в 10:45
Не за что, Леон!
Taylor Swift ответил: 28 марта 2018 в 05:18

Нет, это не имеет значения.

Метод 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
    );
}