减少教义中不必要的联接

时间:2019-08-16 15:23:33

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

为简单起见,让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的关系,因为它在联接中使用它们。

1 个答案:

答案 0 :(得分:0)

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

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

>

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

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

相关问题