bounty还有5天到期。回答此问题可获得+50声望奖励。Condor正在寻找典型答案。
我的Symfony应用程序遇到了问题。我有一个ManyToMany关系,我需要坚持和冲洗。但是,当ManyToMany关系变得太大时,将数据刷新到数据库时会变得非常慢。
我尝试添加fetch="EXTRA_LAZY"
,但似乎没有效果。
我的模型看起来像这样(我已经删除了一些无关紧要的东西):
图像模型
<?php
/**
* @ORM\Entity(repositoryClass=ImageRepository::class)
* @ORM\HasLifecycleCallbacks
*/
class Image
{
/**
* @ORM\ManyToMany(targetEntity=Content::class, inversedBy="images", fetch="EXTRA_LAZY", cascade={"persist"})
*/
private $content;
public function __construct()
{
$this->content = new ArrayCollection();
}
/**
* @return Collection|Content[]
*/
public function getContent(): Collection
{
return $this->content;
}
public function addContent(Content $content): self
{
if (!$this->content->contains($content)) {
$this->content->add($content);
}
return $this;
}
public function removeContent(Content $content): self
{
$this->content->removeElement($content);
return $this;
}
}
内容模型
<?php
/**
* @ORM\Entity(repositoryClass=ContentRepository::class)
* @ORM\HasLifecycleCallbacks
*/
class Content
{
/**
* @ORM\ManyToMany(targetEntity=Image::class, mappedBy="content", fetch="EXTRA_LAZY", cascade={"persist", "remove"})
*/
private $images;
/**
* @return Collection|Image[]
*/
public function getImages(): Collection
{
return $this->images;
}
public function setImages(ArrayCollection $images): void
{
$this->images = $images;
}
public function addImage(Image $image): self
{
if (!$this->images->contains($image)) {
$this->image->add($image);
$image->addContent($this);
}
return $this;
}
public function removeImage(Image $image): self
{
if ($this->images->removeElement($image)) {
$image->removeContent($this);
}
return $this;
}
}
如果我在Image模型中取消注解$this->content[] = $content;
,导入过程就会变得更快。如果我不取消注解,这行刷新数据呈指数增长。我已经将其替换为首选的$this->content->add($content)
这样做并没有提高性能。(两侧,对于Image
和Content
)。
我们正在运行Symfony版本5。3.16和这个应用程序运行在一台机器上与SSD的德数据库服务器,我认为这不是一个硬件问题.
关于保存内容/图像记录。每次插入后都要冲洗。每150个记录我们做一个:
$this->entityManager->clear();
gc_collect_cycles();
有没有人有办法把我往正确的方向推?
1条答案
按热度按时间olmpazwi1#
这是因为调用方法
$this->images->contains($image)
总是将所有集合加载到ProxyObject以检查是否存在https://www.doctrine-project.org/projects/doctrine-collections/en/stable/index.html#contains
https://www.doctrine-project.org/projects/doctrine-orm/en/2.14/tutorials/extra-lazy-associations.html
调用
$em->clear()
后,集合始终为空尝试构建如下:
它将只加载键而不是所有Image对象
同时检查这些地方的SQL日志