Doctrine 2 EntityManagerは、最初のリクエストで時間の損失を引き起こします
-
22-10-2019 - |
質問
最近、Doctrine 2 ormをCodeigniter 2に統合しました。Doctrine2をライブラリとして構成し、Codeigniterで自動装備しました。ページ内で、私は次の方法でDoctrine Entity Managerをインスタンス化します。
private static $em = null;
public function __construct() {
parent::__construct();
$this->em = $this->doctrine->em;
}
そして、必要に応じてエンティティマネージャーを使用し始めます。私が抱えている問題は、各ページリクエストエンティティマネージャーが初期化に時間がかかることです(appr。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
getARTICLE機能は基本的にentityManager-> find()callを作成します。
$currentart = $this->em->find('Entities\Article', $artid);
EntityManager-> createQuery()メソッドを使用している場合でも、1秒待たなければなりません。
すべてのページで、EntityManagerの最初のリクエストのために、約1秒の時間の損失があります。
これは一般的ですか?
この1秒は、EntityManagerがDBへの接続を確立する必要があるという事実から来ていますか?ただし、最初のリクエストの後の関数/要求は非常に高速です。
解決
Doctrineが行う最も時間のかかることは、注釈、XML、YAMLなど、エンティティにメタデータをロードすることです。 Doctrine Lazyは、可能な場合はメタデータにメタデータをロードするため、エンティティの使用を開始するまでパフォーマンスがヒットすることはありません。コードを変更しない限り、メタデータは変更されないため、Doctrineを使用すると、リクエスト全体でメタデータをキャッシュできます。 DQLクエリもSQLに解析する必要があるため、Doctrineはこれに別のキャッシュ構成を提供します。
生産環境では、これらのキャッシュを設定する必要があります(すでに持っているように聞こえますが、これを読んでいる人にとっては):
$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();
もう1つの潜在的なボトルネックは、プロキシクラスの生成です。これが生産環境で正しく構成されていない場合、Doctrineはクラスを生成し、すべてのページロードでファイルシステムに保存します。これらのプロキシクラスは、エンティティのコードが変更されない限り変更されないため、これが発生する必要はありません。物事をスピードアップするには、コマンドラインツール(ORM:生成 - プロキシ)を使用してプロキシを生成し、自動生成を無効にする必要があります。
$configuration->setAutoGenerateProxyClasses(false);
うまくいけば、これはあなたを助けます。さらにいくつかの情報を見つけることができます http://www.doctrine-project.org/docs/orm/2.0/en/reference/improving-performance.html#bytecode-cache