Symfony ManyToMany关系在导入大数据集时变慢

oxiaedzo  于 2023-05-01  发布在  其他
关注(0)|答案(1)|浏览(134)

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)这样做并没有提高性能。(两侧,对于ImageContent)。
我们正在运行Symfony版本5。3.16和这个应用程序运行在一台机器上与SSD的德数据库服务器,我认为这不是一个硬件问题.
关于保存内容/图像记录。每次插入后都要冲洗。每150个记录我们做一个:

$this->entityManager->clear();
gc_collect_cycles();

有没有人有办法把我往正确的方向推?

olmpazwi

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()后,集合始终为空
尝试构建如下:

$this->images->containsKey($image->getId())

它将只加载键而不是所有Image对象
同时检查这些地方的SQL日志

相关问题