我有一个实体,我们称之为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个。
join()
,在7.88ms中加载了373个条目join()
和having()
,这在8.91ms中加载了373个条目leftJoin()
,在8.05毫秒内加载了所有437个条目(不需要)leftJoin()
和having()
,在8.14毫秒内加载了373个条目由于版本1 只使用innerJoin
作为@Chausser指出,是最快的,我会坚持那个。
注意:我并不是说 Version 1 在所有场景和每个硬件上都是最快的,所以有一个跟进问题,是否有人知道性能比较?< / p>
答案 0 :(得分:0)
有关SQL JOIN如何工作的更多信息,请查看此答案:https://stackoverflow.com/a/16598900/1307183
使用join
,这是innerJoin
的别名,正是您想要的。这仅返回Foo
和Bar
中存在条目的记录 - 也就是存在关联/附加实体的位置。这将在SQL中调用INNER JOIN
,如果正确定义了数据库结构,则这是获取所需数据的绝对最佳和最快的方法。
在SQL中使用leftJoin
调用LEFT JOIN
,即使没有与Foo
相关联的Bar
,也会返回bar_id
的所有记录(例如,foo
您null
表中的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"]
子句。