Должен ли я использовать Eloquent ORM или создавать большие соединения с помощью Fluent?

#sql #database #laravel #laravel-4 #eloquent

#sql #База данных #laravel #laravel-4 #eloquent

Вопрос:

Ну, я использую Eloquent ORM для проекта, который я разрабатываю, но это беспокоит меня из-за проблемы с производительностью. Когда я использую только его собственные методы, я вижу по его журналу запросов, что он создает много запросов.

Я пытаюсь извлечь данные из основной таблицы с 4 другими таблицами, одна из которых связана с ней один к одному, а другие — многие ко многим. Eloquent создает для него около 6-7 запросов, и это заставляет меня бояться проблем с производительностью. Затем я удаляю методы Eloquent и создаю гигантские запросы с помощью Fluent, используя множество соединений, из-за чего я теряю читаемость кода и практичность.

Что мне действительно нужно знать: жертвует ли Eloquent производительностью? Должен ли я придерживаться этого или использовать только Fluent? И что лучше, несколько больших объединенных запросов или более мелких?

Комментарии:

1. На самом деле это полностью зависит от вас и вашего приложения. Создайте его с помощью Eloquent . Вероятно, это будет проще и быстрее. Затем, когда вам нужно повысить производительность, выполните рефакторинг того, что необходимо реорганизовать. Также есть другие способы улучшить это — для начала, кэш.

Ответ №1:

Я собираюсь расширить ответ Себастьяна.

У меня тоже есть отношения «многие ко многим» или даже отношения «один ко многим».

Я фактически объединил стиль программирования Eloquent (это проще для глаз) с небольшим количеством совместного взлома с Fluent. Пожалуйста, напоминаем, что Eloquent является расширением Fluent, поэтому вы не жертвуете, если не выполняете запросы bat.

Если вы создаете пользователя, а затем модель телефона с соотношением Один к одному или один ко многим (у пользователя может быть много телефонных номеров)

и вы просто where()-> get(), а затем $users-> phone — это заставит eloquent запускать select * для каждого идентификатора. Здесь используется быстрая загрузка (как указано Себастьяном, но слишком короткая, чтобы на самом деле объяснить), где он предварительно выбирает все требуемые идентификаторы и с нетерпением загружает идентификаторы (вы можете проверить это, запустив профилировщик журнала запросов).

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

Таким образом, это не сокращенное решение «красноречиво, обеспечивающее снижение производительности», если вы не используете его правильно.

Теперь вот небольшой пример того, как я использую eloquent и fluent: В модели книги — я определил функцию области видимости, которая является функцией отношений:

    public function scopeLicensorStatus($query, $licensor_status)
    {
        $query->select('book.*')
            ->leftJoin('licensors as l', 'l.id', '=', 'book.licensor_id')
            ->where('l.status','=',$licensor_status);
    }

    $bookData = Book::
        ->LicensorStatus('active')
        ->where('book.status','=', 'active')
        ->whereIN('book.id',$recommendedIds)
        ->take($limit)
        ->skip($offset)
        ->get();
  

что это делает, так это выполняет соединение для меня как функцию и позволяет мне связывать команды снаружи. В итоге (если вы используете toSql() вместо get() ), вы получите один запрос, который будет соответствовать необработанному SQL, однако, как вы можете видеть: а) код можно использовать повторно, если вы планируете повторно использовать соединение с другими ограничениями, б) вы не жертвуете скоростью, поскольку конечный игровой запрос является единственным (просто нужно правильно его написать), в) выглядит приятнее и читабелен, поэтому нам нравится eloquent.

Надеюсь, этот ответ поможет вам немного глубже погрузиться в eloquent

Комментарии:

1. Спасибо за объяснение. Итак, если я использую быструю загрузку вместо Fluent, что заставляет меня выполнять 2-3 дополнительных запроса (что было бы достигнуто путем свободного использования некоторых соединений и получения большого количества избыточной информации), это, вероятно, не окажет существенного влияния на производительность сервера, не так ли?

2. Как я уже объяснял — Быстрая загрузка не устраняет соединения. Что он делает, так это то, что вместо того, чтобы брать идентификаторы (или отношения) между двумя таблицами и повторно запускать их по отдельности, он предварительно загружает эти идентификаторы, а затем загружает их во втором запросе (следовательно, решая N 1 итерацию). Для одного ко многим это работает очень, очень хорошо. для многих для многих вам может потребоваться выполнить некоторые манипуляции. Как я уже приводил в своем примере, как я сохранял соединения и одновременно использовал eloquent.