Как уменьшить количество запросов к БД, используя вложенный список элементов в теге <select>? - PullRequest
1 голос
/ 11 июня 2019

Ларавел 5.8: Я получаю слишком много запросов, когда использую вложенный список элементов.

Это для меню в представлении. Я сделал вложенное меню элементов, но мне кажется, что оно требует слишком много запросов (10 дополнительных запросов для моего списка из 30 элементов), хотя я использовал «нетерпеливые нагрузки».

В модели:

public function children()
{
    return $this->hasMany(Item::class, 'parent_id', 'id');
}

Его репозиторий: (используется рьяные нагрузки [с])

public function getListOfItemTitles()
{
    $columns = ['id', 'parent_id', 'title'];

    $result = $this->startConditions()
        ->select($columns)
        ->with(['children:id,title,parent_id'])
        ->get();
    return $result;
}

А вид:

<select name="item_id" id="item_id" class="form-control" required>
    @foreach($itemList as $itemOption)
        @if($itemOption->parent_id == 1)
            <optgroup label="{{ $itemOption->title }}">
                @foreach($itemOption->children as $children)
                    <option value="{{ $children->id }}">
                        {{ $children->title }}
                    </option>
                    @foreach($children->children as $subchildren)
                        <option value="{{ $subchildren->id }}">
                            —{{ $subchildren->title }}
                        </option>
                    @endforeach
                @endforeach
            </optgroup>
        @endif
    @endforeach
</select>

Вот мои вопросы:

select `id`, `parent_id`, `title` from `items` where `items`.`deleted_at` is null
select `id`, `title`, `parent_id` from `items` where `items`.`parent_id` in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30) and `items`.`deleted_at` is null
select * from `items` where `items`.`parent_id` = 4 and `items`.`parent_id` is not null and `items`.`deleted_at` is null
select * from `items` where `items`.`parent_id` = 8 and `items`.`parent_id` is not null and `items`.`deleted_at` is null
select * from `items` where `items`.`parent_id` = 12 and `items`.`parent_id` is not null and `items`.`deleted_at` is null
select * from `items` where `items`.`parent_id` = 16 and `items`.`parent_id` is not null and `items`.`deleted_at` is null
select * from `items` where `items`.`parent_id` = 20 and `items`.`parent_id` is not null and `items`.`deleted_at` is null
select * from `items` where `items`.`parent_id` = 26 and `items`.`parent_id` is not null and `items`.`deleted_at` is null
select * from `items` where `items`.`parent_id` = 27 and `items`.`parent_id` is not null and `items`.`deleted_at` is null
select * from `items` where `items`.`parent_id` = 28 and `items`.`parent_id` is not null and `items`.`deleted_at` is null
select * from `items` where `items`.`parent_id` = 29 and `items`.`parent_id` is not null and `items`.`deleted_at` is null
select * from `items` where `items`.`parent_id` = 30 and `items`.`parent_id` is not null and `items`.`deleted_at` is null

Буду рад, если вы поможете мне уменьшить количество запросов. Любые дополнительные советы в этом случае будут очень полезны, так как я новичок в PhP и Laravel.

1 Ответ

1 голос
/ 11 июня 2019

Вы также должны загружать дочерних элементов:

$columns = ['id', 'parent_id', 'title'];

$result = $this->startConditions()
    ->select($columns)
    ->with(['children:id,title,parent_id', 'children.children:id,title'])
    ->get();
return $result;

Рассмотрите следующий пример из этой статьи: https://laravel -news.com / eloquent-eager-loading

$posts = App\Post::with('author.profile')->get();
$posts->map(function ($post) {
    return $post->author->profile;
});

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...