gpt4 book ai didi

mysql - Doctrine 中仅加载具有附加实体的实体的最佳方法

转载 作者:行者123 更新时间:2023-11-29 03:21:09 25 4
gpt4 key购买 nike

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

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

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

我现在想在一种情况下只加载至少分配了一个 Bar 实体的 Foo 实体。以前,有一个 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.88 毫秒内加载了 373 个条目
  • 版本 2: 使用 join()having(),这在 8.91 毫秒内加载了 373 个条目
  • 版本 3: 仅使用 leftJoin(),它在 8.05 毫秒内加载了所有 437 个条目(这不是我们想要的)
  • 版本 4: 使用 leftJoin()having(),这在 8.14 毫秒内加载了 373 个条目

正如@Chausser 指出的那样,版本 1 仅使用 innerJoin 是最快的,因此我会坚持使用该版本。

注意:我并不是说版本 1 在所有场景和所有硬件上都是最快的,所以这是一个后续问题,有人知道性能比较吗?

最佳答案

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

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

使用 leftJoin 在 SQL 中调用 LEFT JOIN,它返回 Foo 中的所有记录,即使没有 Bar 与之关联(例如,foo 表中的 bar_id 将为 null)。

您没有理由在您描述的任何上述场景中使用having()。如果您想进一步过滤,您可以使用 ->addWhere() 函数来实现。如果您在原始查询中选择聚合数据(例如 SELECT SUM(field) AS sum_field),您只会希望使用 having() 子句。

关于mysql - Doctrine 中仅加载具有附加实体的实体的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44810230/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com