Doctrine 2 EntityManager会在第一个请求中导致时间丢失

时间:2011-07-23 17:58:51

标签: php doctrine-orm codeigniter-2

最近我将Doctrine 2 ORM集成到CodeIgniter 2.我将Doctrine 2配置为库并在CodeIgniter中自动加载它。在页面中,我通过以下方式实例化doctrine实体管理器:

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

GetArticle函数基本上是一个EntityManager-> find()调用:

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

即使我使用EntityManager-> createQuery()方法,我也必须等待1秒钟。

在每个页面中,由于EntityManager的第一个请求,我有大约1秒的时间损失。

这是常见的吗?

这1秒是否来自EntityManager需要与DB建立连接的事实?第一次请求后的函数/请求非常快。

1 个答案:

答案 0 :(得分:1)

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();

另一个潜在的瓶颈是生成代理类。如果在生产环境中未正确配置,则Doctrine将生成类并在每次加载页面时将它们保存到文件系统。除非实体的代码发生更改,否则这些代理类不会更改,因此再次发生这种情况也是不必要的。为了加快速度,您应该使用命令行工具(orm:generate-proxies)生成代理并禁用自动生成:

$configuration->setAutoGenerateProxyClasses(false);

希望这会帮助你。可以在http://www.doctrine-project.org/docs/orm/2.0/en/reference/improving-performance.html#bytecode-cache

找到更多信息