Доктрина 2 EntityManager вызывает потери времени в первом запросе

StackOverflow https://stackoverflow.com/questions/6802254

  •  22-10-2019
  •  | 
  •  

Вопрос

Недавно я интегрировал доктрину 2 ORM в CodeIgniter 2. Я настроил Doctrine 2 как библиотеку и автозагружал ее в CodeIgniter. В рамках страницы I создание менеджера объектов доктрины следующим образом:

private static $em = null;

public function __construct() {
    parent::__construct();
    $this->em = $this->doctrine->em;
}

А потом я начинаю использовать менеджер объектов, когда это необходимо. Проблема, которая у меня есть, заключается в том, что на каждой странице менеджер по запросу запроса требуется некоторое время для инициализации (атмосфера 1 секунды). Это заставляет пользователя ждать, пока страница не будет загружена. Ниже вы можете увидеть некоторые результаты производительности, которые я измерил:

BENCHMARKS  
Loading Time: Base Classes          0.0166
Doctrine                            0.0486
GetArticle                          1.0441
Functions                           0.0068
Controller Execution Time           1.1770
Total Execution Time                1.1938

Функция Getarticles в основном делает вызов EntityManager-> find ():

$currentart = $this->em->find('Entities\Article', $artid);

Я должен подождать эту 1 секунду, даже если я использую метод EntityManager-> CreateQuery ().

На каждой странице у меня есть потери времени примерно 1 секунды из -за первого запроса EntityManager.

Это обычное дело?

Приходит ли это 1 секунда из того факта, что EntityManager должен установить связь с БД? Функции/запросы после первого запроса довольно быстрые.

Это было полезно?

Решение

Самая трудоемкая вещь, которую делает доктрина, - это загрузка метаданных для ваших сущностей, будь то аннотации, XML или YAML. Доктрина Lazy загружает метаданные, когда это возможно, так что вы не увидите, чтобы производительность попала, пока не начнете использовать объекты. Поскольку метаданные не меняются, если вы не внесете изменения в свой код, доктрина позволяет вам кэшировать метаданные по запросам. Запросы DQL также должны быть проанализированы в SQL, поэтому доктрина обеспечивает еще одну конфигурацию кэширования для этого.

В производственной среде вы должны установить эти кеши (похоже, у вас уже есть, но для других читающих это):

$cache = new \Doctrine\Common\Cache\ApcCache(); // or MemcacheCache $configuration->setMetadataCachImpl($cache); // caches metadata for entities $configuration->setQueryCachImpl($cache); // caches SQL from DQL queries

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

$em->getMetadataFactory()->getAllMetadata();

Другим потенциальным узким местом является поколение прокси -классов. Если это не настроено правильно в производственной среде, доктрина будет генерировать классы и сохранить их в файловой системе при каждой загрузке страницы. Эти прокси -классы не изменяются, если код субъекта не изменится, поэтому снова не нужно. Чтобы ускорить ситуацию, вы должны генерировать прокси, используя инструмент командной строки (ORM: Generate-Proxies) и отключить автогенерацию:

$configuration->setAutoGenerateProxyClasses(false);

Надеюсь, это вам поможет. Некоторая дополнительная информация может быть найдена в http://www.doctrine-project.org/docs/orm/2.0/en/reference/improving-performance.html#bytecode-cache

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top