如何在Symfony2中优化DQL查询?

时间:2013-01-03 14:54:06

标签: symfony doctrine doctrine-orm query-optimization

我有一个名为 Abono 的实体,它是Check,Efectivo,Debito等其他几个实体的父类。在我的应用程序中,我使用带有这样的DQL语句的存储库类查询所有Abono类实例的对象(代码是真实类型的简化版本):

$dql = "SELECT ab FROM FranquiciaBundle:Abono AS ab";
return $em->createQuery($dql)
          ->getResult();

在我的模板中,我正在显示这样的结果(再次,简化代码):

{% for abono in abonos %}
    <tr>
        <td>{{ abono.id }}</td>
        <td>{{ abono.tipo }}</td>
    </tr>
{% endfor %}

我在该表上有5000条记录,并且分析器告诉我该应用程序正在按照我预期的那样达到数据库的5000倍,所以我使用getArrayResult()而不是{{}更改了que存储库1}}但问题是句子getResult()是对象的方法调用,而不是存储在数据库中的属性,所以它永远不会被水合成结果数组。

所以我的问题是,我怎样才能让一个对象数组一次只能访问数据库?

UPDATE: Abono类的方法{{ abono.tipo }}返回每个对象的Late Static Binding类名,它不是关联。

getTipo()

3 个答案:

答案 0 :(得分:6)

好的,我找到了问题的根源。

当查询对象的反面时,doctrine会始终获取这些实体以创建代理实例,即使这些实体不是在控制器或模板中需要。因此,配置文件栏向我展示的数据库的大量点击,实际上是在学习搜索我不想要的信息的方式。

解决方案是强制在存储库中使用部分加载,如下所示:

$dql = "SELECT ab FROM FranquiciaBundle:Abono AS ab";
return $em->createQuery($dql)
          ->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
          ->getResult();

可以找到更多信息here

答案 1 :(得分:2)

您可以使用获取联接来获取相关信息并将其与第一个查询一起保存。

“SELECT ab,tipo FROM FranquiciaBundle:Abono AS ab JOIN ab.tipo”

另见: http://doctrine-orm.readthedocs.org/en/2.0.x/reference/dql-doctrine-query-language.html#joins

答案 2 :(得分:1)

Erik是对的,不过你不应该去sql进行优化,doSelectJoinAll会做的。