Doctrine中仅加载具有附加实体的实体的最佳方式

时间:2017-06-28 18:40:58

标签: mysql symfony join doctrine-orm group-by

我有一个实体,我们称之为Foo,第二个Bar

Foo可以(但不必)分配一个或多个Bar条目。它看起来像这样:

/**
 * @ORM\OneToMany(targetEntity="Bar", mappedBy="foo")
 * @ORM\OrderBy({"name" = "ASC"})
 */
private $bars;

我现在只想在一个案例中加载至少分配了Foo个实体的Bar个实体。以前,有一个foreach循环遍历所有Foo条目,如果已​​分配条目,则Foo条目已分配给数组。

我目前的实现是FooRepository一个名为findIfTheresBar的函数,如下所示:

$qb = $this->_em->createQueryBuilder()
        ->select('e')
        ->from($this->_entityName, 'e')
        /* some where stuff here */
        ->addOrderBy('e.name', 'ASC')
        ->join('e.bars', 'b')
        ->groupBy('e.id');

这是加载此类条目的正确方法吗?有更好(更快)的方式吗?感觉好像在查询中应该有having(...)

修改
我进一步调查了一下。该查询应返回437个条目中的373个。

  • 版本1:仅使用join(),在7.88ms中加载了373个条目
  • 版本2:使用join()having(),这在8.91ms中加载了373个条目
  • 版本3:仅使用leftJoin(),在8.05毫秒内加载了所有437个条目(不需要)
  • 第4版:使用leftJoin()having(),在8.14毫秒内加载了373个条目

由于版本1 只使用innerJoin作为@Chausser指出,是最快的,我会坚持那个。

注意:我并不是说 Version 1 在所有场景和每个硬件上都是最快的,所以有一个跟进问题,是否有人知道性能比较?< / p>

1 个答案:

答案 0 :(得分:0)

有关SQL JOIN如何工作的更多信息,请查看此答案:https://stackoverflow.com/a/16598900/1307183

使用join,这是innerJoin的别名,正是您想要的。这仅返回FooBar中存在条目的记录 - 也就是存在关联/附加实体的位置。这将在SQL中调用INNER JOIN,如果正确定义了数据库结构,则这是获取所需数据的绝对最佳和最快的方法。

在SQL中使用leftJoin调用LEFT JOIN,即使没有与Foo相关联的Bar,也会返回bar_id的所有记录(例如,foonull表中的1}}将是having())。

您没有理由在上述任何情景中使用->addWhere()。如果您想进一步过滤,可以使用having()功能进行过滤。如果您在原始查询中选择汇总数据(例如SELECT SUM(field) AS sum_field),则只需要使用["1.0", "1.10", "1.2", "1.6", "1.11.1", "1.3.1", "1.8", "1.11.2", "1.7.1", "1.1.3", "1.7", "1.6.1", "1.6.2", "1.9", "1.4.1", "1.4.1.1", "1.4", "1.6.3", "1.4.1.2", "1.5", "1.3", "1.11", "1.1.2"] 子句。