Влияют ли отношения Doctrine на производительность приложений? - PullRequest
0 голосов
/ 05 ноября 2019

Я работаю над проектом Symfony с новой командой, и они решают прекратить использовать отношения Doctrine, насколько это возможно, из-за проблем с производительностью.

Например, мне нужно хранить идентификатор своего "отношения""вместо использования отношения ManyToOne.

Но мне интересно, если это реальная проблема?

Дело в том, что это меняет способ кодирования для получения информации и т. д.

1 Ответ

1 голос
/ 05 ноября 2019

Скорее всего, проблема производительности связана с тем, что запросы не оптимизированы.

Если вы позволите Doctrine (компонент Symfony, который обрабатывает запросы) выполнять запросы самостоятельно (с помощью findBy(), findAll(), findOneBy() и т. Д.), Он сначала получит то, что вы запросили, затем выполнитебольше запросов, так как для этого потребуются данные из других таблиц.

Давайте возьмем самый распространенный пример - библиотеку.

Entities

  • Книга
  • Автор
  • Полка

Отношения

  • Один Book имеет один Author, но один Author может иметь много Books (Book <= ManyToOne => Author)
  • Один Book хранится в одном Shelf (Book <= OneToOne => Sheilf)

Теперь, если вы запросите Book, Doctrine также получит Shelf, так как это отношение OneToOne.
Но оно не получит Author. В вашем объекте вы будете иметь доступ только к book.author.id, поскольку эта информация находится в самом Book.

Таким образом, если в вашем представлении Twig вы делаете что-то вроде {{ book.author.name }}, так как информация былане извлекается в начальном запросе, Doctrine добавит дополнительный запрос для извлечения данных об авторе книги.

Таким образом, чтобы предотвратить это, вы должны настроить свой запрос так, чтобы он получал необходимые данные за один раз. вот так:

public function getBookFullData(Book $book) {
    $qb=$this->createQueryBuilder('book');

    $qb->addSelect('shelf')
       ->addSelect('author')
       ->join('book.shelf', 'shelf')
       ->join('book.author', 'author');

    return $qb->getQuery()->getResult();
}

С помощью этого пользовательского запроса вы можете получить все данные одной книги за один раз, таким образом, Doctrine не придется делать дополнительный запрос.

Таким образом, хотя пример довольно прост, я уверен, что вы понимаете, что в больших проектах предоставление свободного доступа к Doctrine просто увеличит количество дополнительных запросов.
Один из моих проектов до оптимизации достиг 1500 запросовна страницу загрузки ...

С другой стороны, игнорировать отношения в базе данных нехорошо. Фактически, база данных быстрее с внешними ключами и индексами, чем без.

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

[SIDE NOTE]

Вы также можете изменить метод выборки в аннотации вашего объекта, чтобы «оптимизировать» предварительно сделанные запросы Doctrine. .

  • fetch="EXTRA_LAZY
  • fetch="LAZY
  • fetch="EAGER

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

...