减少 Doctrine 中不必要的连接
Reducing unnecessary joins in Doctrine
为了简单起见,让 Symfony 中有 2 个实体。第一个称为 Job
,第二个称为 Field
(Job
的类别)。每个作业可以属于多个字段。 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
table)不需要接缝。有没有办法删除 this/tell 不这样做的教义?
理论上 Doctrine 应该知道 f.id
和 jtf.field_id
的关系,因为它在连接中使用它们。
这是正确的行为,因为如果没有对 Job 对象的连接调用 getFields()
将无法访问要显示的数据。
您可能能够通过在您的 $fields 注释上使用延迟获取来影响这一点,但是如果您调用 getFields() 它会进一步结束 运行查询以获取数据。
@ORM\ManyToMany(targetEntity="App\Entity\Field", fetch="EXTRA_LAZY")
但是,除非您要解决特定问题,否则我会顺其自然。这是 ORM 做 ORM 做的事。
为了简单起见,让 Symfony 中有 2 个实体。第一个称为 Job
,第二个称为 Field
(Job
的类别)。每个作业可以属于多个字段。 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
table)不需要接缝。有没有办法删除 this/tell 不这样做的教义?
理论上 Doctrine 应该知道 f.id
和 jtf.field_id
的关系,因为它在连接中使用它们。
这是正确的行为,因为如果没有对 Job 对象的连接调用 getFields()
将无法访问要显示的数据。
您可能能够通过在您的 $fields 注释上使用延迟获取来影响这一点,但是如果您调用 getFields() 它会进一步结束 运行查询以获取数据。
@ORM\ManyToMany(targetEntity="App\Entity\Field", fetch="EXTRA_LAZY")
但是,除非您要解决特定问题,否则我会顺其自然。这是 ORM 做 ORM 做的事。