学说在多对多协会中渴望渴望



使用Symfony 3.2和Doctrine 2.5,我很难理解"渴望"如何在多对多和多一的关系中起作用。

可以说,我们有两个实体,用户和网站,以及一个多对多的关联:

class User
{
    /**
     * @ORMManyToMany(targetEntity="Site", inversedBy="users", fetch="EAGER")
     * @ORMJoinTable(name="user_site")
     */
    private $sites;
}
class Site
{
    /**
     * @ORMManyToMany(targetEntity="User", mappedBy="sites")
     */
    private $users;
}

在我的控制器中,我只需致电

 $users = $this->getDoctrine()->getRepository('CoreBundle:User')->findAll();

我只想在用户表上看到1个查询,并在网站表上加入一个查询,但是我得到了n 1个查询。我还进行了一些与一对一关联的测试,并获得了相同的结果。

我知道我可以使用DQL自己进行加入,但我想了解"渴望"的工作方式。

在多对多和一对一的关联上以"急切"的"渴望"的预期行为是什么?

多到马尼

many-to-many关联上提取eager的预期行为正是您所描述的。

如果我们在代码中访问3个Post对象,这些对象与Tags有一个many-to-many关联,则发生4个查询,无论我们使用fetch="EAGER"还是fetch="LAZY"

SELECT t0.id AS id_1, t0.title AS title_2 FROM post t0
SELECT t0.id AS id_1, t0.title AS title_2 FROM tag t0 INNER JOIN post_tag ON t0.id = post_tag.tag_id WHERE post_tag.post_id = 1
SELECT t0.id AS id_1, t0.title AS title_2 FROM tag t0 INNER JOIN post_tag ON t0.id = post_tag.tag_id WHERE post_tag.post_id = 2
SELECT t0.id AS id_1, t0.title AS title_2 FROM tag t0 INNER JOIN post_tag ON t0.id = post_tag.tag_id WHERE post_tag.post_id = 3

一到一对

one-to-many关联上使用eager的预期行为不同。通过使用fetch="EAGER",我们可以减少查询数量。

如果我们在代码中访问3个Post对象,该对象与Comments具有one-to-many关联时,使用fetch="EAGER"时会发生1个查询:

SELECT
    t0.id AS id_1,
    t0.title AS title_2,
    t3.id AS id_4,
    t3.title AS title_5,
    t3.post_id AS post_id_6
FROM post t0
LEFT JOIN comment t3 ON t3.post_id = t0.id

但是,如果我们使用 fetch="LAZY"

,请进行4个查询。
SELECT t0.id AS id_1, t0.title AS title_2 FROM post t0
SELECT t0.id AS id_1, t0.title AS title_2, t0.post_id AS post_id_3 FROM comment t0 WHERE t0.post_id = 1
SELECT t0.id AS id_1, t0.title AS title_2, t0.post_id AS post_id_3 FROM comment t0 WHERE t0.post_id = 2
SELECT t0.id AS id_1, t0.title AS title_2, t0.post_id AS post_id_3 FROM comment t0 WHERE t0.post_id = 3

我的结论

永远不要在many-to-many关联上使用fetch="EAGER",因为它只能通过从DB中加载更多的数据来减慢您的性能(但永远无法改进(。如果可以改善您的性能,请选择使用one-to-many上的fetch="EAGER"

如果我们需要减少many-to-many关联的查询,我们必须编写自定义DQL查询。

相关内容

  • 没有找到相关文章

最新更新