PankovAlxndr
@PankovAlxndr
Fullstack web developer

Как уменьшить количество запросов?

Здравствуйте, подскажите как правильно организовать код и уменьшить количество запросов?

у меня есть некая модель, пусть будет называться "Модель 1"
еще есть модель, пусть будет называться "Модель 2" и она дочерняя для "Модель 1"
еще есть модель, пусть будет называться "Модель 3" и она дочерняя для "Модель 2"

Или для предметной области
- Модель "Договор 1"
- Модель "Узел 2"
- Модель "Оборудование 3"
- Модель "Узел 2"
- Модель "Другое Оборудование 3"

примерная такая структура, вложенность может быть 3-4 уровня
Все эти модель связаны между собой релейшенами hasOne\hasMany\BelongsTo....
все это работает

На экран это выводить через API Resources

вот так выводится ресурс для Договора (верхний уровень)
public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        ..........
        'unit' => UnitResource::collection($this->units), // тут выводим все узлы догоовра
    ];
}


вот так выводится ресурс для Узла (2ой уровень)
public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        ..........
        'unit' => EquipmentResource::collection($this->units), // тут выводим все оборудование для Узла
    ];
}


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

Суть задачи на самом деле не в этом это вводная часть
Суть:
Вот у нас есть Договора, у договоров есть Узлы учета, а у каждого узла учета есть какое-то оборудование

и бизнес логика создает заявки на изменение эти данных
те есть заявка на изменение узла или оборудования в узле и тп
заявки имеют статусы "в работе" \ "завершена"
категорию и сами данные (тело заявки) в json формате
таблицы: Заявки, Атрибуты заявок

так вот
1) у нас есть роут, который выводит на экран агрегированную информацию, те выводит один договор и все у него узлы с оборудованием, на такой один договор может быть найдено 100 оборудований (100 записей в БД)
2) Встала задача показывать сколько активных заявок мы имеем сейчас на выбранных договор, узел, оборудование, Те мне нужно постучать в базу и отфильтровать заявки (посчитать их хотя бы ->count())

Мой вопрос в том что я не знаю где и как это правильно сделать?

Сейчас у меня есть 3 API Resources
Договор - Узел - Оборудование

Когда я дергаю вывести мне Договор, то он оттуда через ***Resource::collection(Model::relation)
пробирается до самого низа и все выводит, те отрабатывают все 3 php файла для генерации массива

сейчас я решил в лоб и я В КАЖДОМ из 3ех файлов делаю дополнительные запросы
Пример
1) дергаем агрегатную информацию по договору, вызывается return ContractResource::make($contact)
2) попадаем внуть ContractResource.php
3) внутри него я делаю 2 запроса
3.1) на получение активных заявок нужного типа (я получаю id заявок пригодных для поиска (грубо говоря категорию + какие то еще фильтры))
3.2) среди этих заявок я ищу только те, которые относятся к текущему Договору (фильтр JSON)
(те у меня таблица ЗАЯВКА с общими данные для каждого типа заявки (1 запрос) и таблица АТТРИБУТЫ_ЗАЯВОК, которая уже содержит JSON данные по заявке (2ой запрос))
4) делаю эти 2 запрос я получаю данные и прикрепляю их к выводу
5) далее через релейшен я проваливаюсь в новый ресурс (вывожу узел этого договора)
5) попадаем внуть UntiResource.php
6) внутри него я делаю 2 запроса (причем первый запрос ТОЧНО ТАКОЙ ЖЕ КАК И ВЫШЕ, те заявки в одной категории)
6.1) на получение активных заявок нужного типа (я получаю id заявок пригодных для поиска (грубо говоря категорию))
6.2) среди этих заявок я ищу только те, которые относятся к текущему Узлу (фильтр JSON)
7) делаю эти 2 запрос я получаю данные и прикрепляю их к выводу
8) далее через релейшен я проваливаюсь в новый ресурс (вывожу оборудование этого узла)
9) попадаем внуть EquipmentResource.php
10) внутри него я делаю 2 запроса (причем первый запрос ТОЧНО ТАКОЙ ЖЕ КАК И ВЫШЕ, те заявки в одной категории)
10.1) на получение активных заявок нужного типа (я получаю id заявок пригодных для поиска (грубо говоря категорию))
10.2) среди этих заявок я ищу только те, которые относятся к текущему Узлу (фильтр JSON)

Мне кажется у меня жуткий оверхед
и делать запросу внутри метода toArray класса ресурса - вообще не верно

подскажите как мне организовать такую архитектуру правильно, чтобы не был лишних\дублирующих запросов?

Итого: есть 3-4 модели каждая ссылается на следующую, мы их выводим на одной странице и в других таблицах у нас есть так же данные которые нужно найти и присоединить на каждом из уровней

Вот такая дичь
60d08529bff78784341847.png

база
60d087d778222962545570.png
60d087e0c50a4148064582.png
  • Вопрос задан
  • 223 просмотра
Пригласить эксперта
Ответы на вопрос 2
glaphire
@glaphire Куратор тега PHP
PHP developer
Возможно лучшим выходом будет использование raw запросов с кучей джоинов, их проще контролировать и меньше оверхед
Ответ написан
Комментировать
@jazzus

чтобы не был лишних\дублирующих запросов?

Вложенные with и withCount и запросы внутри них.


читал про жадную загрузку с whenLoaded(прикольно

whenloaded это не жз просто проверка.

ресурсы работают с загруженными данными. если делать из них запросы в бд как в примере, получишь по запросу на каждый элемент коллекции
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы