【问题标题】:Doctrine 2 getResult() takes a lot of time教义 2 getResult() 需要很多时间
【发布时间】:2014-05-06 19:17:53
【问题描述】:

我使用教义 2 开发 symfony 2 应用程序。我的代码是:

$userSites = $this->getDoctrine()->getManager()
            ->createQuery('SELECT us, s FROM MyMainBundle:UserSite us JOIN us.site s WHERE us.user = :user_id')
            ->setParameter('user_id', $user_id)
            ->getResult();

它通常返回大约 7000 多条记录。当我将此查询直接传递给 mysql(使用 getSql() 并粘贴到 phpmyadmin)时,它需要 0,008 秒。但是 getResult() 大约需要 20-30 秒。 :( 为什么?我可以加快速度吗?

【问题讨论】:

  • 我遇到了这个问题,但使用了 Doctrine 1。我已经解决了将水合模式从对象切换到数组的问题。我认为你也可以在 Doctrine 2 上做到这一点。试试这个:$userSites = $this->getDoctrine()->getManager()->createQuery('SELECT us, s FROM MyMainBundle:UserSite us JOIN us.site s WHERE us.user = :user_id')->setParameter('user_id', $user_id)->getResult(Doctrine\ORM\Query::HYDRATE_ARRAY);
  • 我将 getResult() 更改为 getArrayResult()。现在大约需要 5 秒。但我觉得还是太长了……
  • 您能否发布由 Doctrine 生成的查询,以便我们检查它与原始查询之间的区别?
  • 您是否可能在您的实体中执行大量 CPU 资源?
  • @vsmoraes 即使 5 年后,您的解决方案仍然适用!

标签: php mysql symfony doctrine-orm


【解决方案1】:

你确定 phpmyadmin 会做一个没有 LIMIT 的查询吗?默认情况下,它会添加 LIMIT 0、30 或类似的东西,并进行分页。如果您在本地计算机、共享托管服务器或 VPS 上工作,我会说 20 到 30 秒是正常的,因为它们使用缓存,例如 apc。

在现实世界中,您永远不应该进行会返回这么多结果的查询。您应该研究批处理的教义。这就是我使用的,效果很好。基本上,您将在循环中进行更多“较小”的查询。如果你需要一个如何做到这一点的例子,我可以给你代码示例。

而且当您进行复杂查询并且时间很重要时,请尝试使用 DBAL(数据库抽象层),以避免使用复杂对象进行查询。

【讨论】:

    【解决方案2】:

    Doctrine 比仅使用 mysql_query() 慢并不奇怪,但 20-30 秒的 7000 个结果比我预期的要多。也许您可以分析您的应用程序,例如使用 xhprof 查看哪个部分消耗了异常多的内存/时间。

    正如@vsmoraes 在评论中指出的那样,您可以将 FETCH_MODE 切换为数组。您还可以缓存查询/结果或分页(仅获取部分结果,例如每页 100 个)。

    【讨论】:

      猜你喜欢
      • 2020-03-19
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-02
      相关资源
      最近更新 更多