【问题标题】:Reducing unnecessary joins in Doctrine减少 Doctrine 中不必要的连接
【发布时间】:2019-08-16 15:23:33
【问题描述】:

为简单起见,让 Symfony 中有 2 个实体。第一个称为Job,第二个称为FieldJob 的类别)。每个作业可以属于多个领域。 Job 知道它的字段,而 Field 实体对作业一无所知。

// Job.php

/**
 * @ORM\ManyToMany(targetEntity="App\Entity\Field")
 * @ORM\JoinTable(name="job_to_fields",
 *     joinColumns={@ORM\JoinColumn(name="job_id", referencedColumnName="id")},
 *     inverseJoinColumns={@ORM\JoinColumn(name="field_id", referencedColumnName="id")}
 * )
 */
private $fields;

当我们要加载字段 [1, 2, 3] 的所有作业时,我希望类似

SELECT j.*
FROM job j
INNER JOIN job_to_fields jtf ON j.id = jtf.job_id
WHERE /* some other parameters */jtf.field_id IN (1, 2, 3)

实际上 Doctrine 构造了这个 SQL 语句:

SELECT j.*
FROM job j
INNER JOIN job_to_fields jtf ON j.id = jtf.job_id
INNER JOIN field f ON f.id = jtf.field_id
WHERE /* some other parameters */f.id IN (1, 2, 3)

第二个连接(到field 表)是不必要的。有没有办法删除这个/告诉教义不要这样做?
理论上,Doctrine 应该知道 f.idjtf.field_id 的关系,因为它在连接中使用它们。

【问题讨论】:

    标签: symfony join doctrine-orm doctrine query-optimization


    【解决方案1】:

    这是正确的行为,因为如果没有对 Job 对象调用 getFields() 的联接,将无法访问要显示的数据。

    可能可以通过在 $fields 注释上使用延迟获取来影响这一点,但是如果您调用 getFields(),它最终会运行进一步的查询以获取数据。 p>

    @ORM\ManyToMany(targetEntity="App\Entity\Field", fetch="EXTRA_LAZY")

    但是,除非您要解决特定问题,否则我会顺其自然。这是 ORM 在做 ORM 所做的事情。

    【讨论】:

      猜你喜欢
      • 2011-11-10
      • 2022-12-17
      • 1970-01-01
      • 2021-01-12
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多