Стремительная загрузка с ограничениями порождает слишком много запросов. Как я могу облегчить это?

У меня есть 4 таблицы, которые связаны в базе данных и в моделях следующим образом:

Users (hasMany(communities), hasMany(comments), hasMany(submissions))
Communities (belongsTo(user), hasMany(submissions))
Submissions (belongsTo(community), belongsTo(user), hasMany(comments))
Comments (belongsTo(user) , belongsTo(submission))

Сейчас. Если я использую отношения, чтобы получить, скажем 25 последних представлений, как это:

$submissions = Submission::simplePaginate(25);

У меня 76 выполненных запросов после использования foreach для просмотра результатов.

Если я использую готовую загрузку со следующим

$submissions = Submission::with(['user', 'community', 'comments'])->simplePaginate(25);

Я получил 4 запроса, что является оптимальным (я думаю).

Теперь моя проблема в том, что в сообществах у меня есть поле базы данных с именем active, которое принимает 1 для активного сообщества и 0 для неактивного. Как вы уже догадались, предыдущий запрос возвращает все, включая неактивные сообщества.

Я думал об ограничениях загрузки, поэтому я использовал следующее:

$submissions = Submission::with([
'community' => function($query) {
$query->active();
}
]
)->with(['user', 'comments'])->simplePaginate(25);

Это все еще делает эту работу с 4 запросами, но теперь я столкнулся с другой проблемой. Этот метод фильтрует неактивные сообщества, но по-прежнему загружает сообщения, пользователей и комментарии. И теперь я остаюсь с результатом, где я получаю сообщения от неактивных сообществ.

Наконец, после прочтения этого сообщества я попытался сделать следующее:

   $submissions = Submission::whereHas(
'community', function($query) {
$query->active();
}
)->with(['user', 'comments'])->simplePaginate(20);

Таким образом, вместо использования -> with () я использовал -> whereHas (), как кто-то предложил. Однако, хотя это дает правильные результаты, т. Е. Дает мне сообщения, комментарии и пользователей только из активных сообществ, теперь оно делает это в 23 запросах, в соответствии с отзывами, полученными от Laravel Debugbar.

Это нормально? Это единственный способ сделать это через Eloquent без написания пользовательских запросов с объединениями? Дует ли я 23 запроса непропорционально?

Любая помощь будет принята с благодарностью.

3

Решение

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

Чтобы оптимизировать это, вы можете сделать конкретные отношения в Submission модель, в которой вы активно фильтруете активные сообщества.

// Submission model

public function activeCommunities (){

return $this->hasMany(Community::class)->whereActive(true);
}

Теперь ваш запрос будет выглядеть так:

$submissions = Submission::with(['user', 'comments', 'activeCommunities])
->simplePaginate(25);

Это должно выполнить 4 запроса, я считаю.

Надеюсь, это поможет вам.

1

Другие решения

Итак, немного поработав, я нашел решение, но я все еще не уверен. Я публикую это для дальнейшего использования, так как это решило мою проблему. Код, который я использовал, следующий

  $submissions = Submission::whereHas(
'community', function($query) {
$query->where('is_active', true);
}
)->with(['user', 'community'])->withCount('comments')
->paginate(25);

Итак, я попытался с помощью whereHas() проверить существование моделей, прежде чем загружать community модель, если это имеет смысл? Похоже, я получил желаемые результаты, поскольку теперь я выполняю всего 4 запроса, чтобы получить все представленные материалы и связанную с ними информацию, фильтруя неактивные сообщества.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector