我正在使用带有 doctrine 2.4 的 Symfony 2.8
我有一个具有一对多、自引用关联映射的实体
实体:
ID
姓名
parent_id
示例:
id: 1
name: A
parent_id: null
id: 2
name: B
parent_id = 1
id: 3
name: C
parent_id = 2
id: 4
name: D
parent_id = 3
我写了一个函数来查找父项的所有嵌套子项的 ID。
public function getAllChildrenIdRecursively($entity)
{
$result = array();
if (count($entity->getChildren()) > 0) {
$result[] = $entity->getId();
foreach ($entity->getChildren() as $child) {
$result = array_merge($result, $this->getAllChildrenIdRecursively($child)) ;
}
}
return $result;
}
如果我调用此函数 getAllChildrenIdRecursively(2),那么我将得到 3、4。
此函数有效,但我的问题是它在数据库中生成了太多查询,几乎需要 1.5 秒。查询生成超过 2500 个,总结果 = 2600,总行 = 5000
如何减少查询时间?
任何帮助将不胜感激! 谢谢
最佳答案
对于您的 child 实现,您没有有效优化代码的解决方案。您必须更改您的实现方式,以便仅通过一个请求即可遍历您所有的 child 和子 child 。树实现是一种更好的解决方案,因为通过一个 SQL 请求,您可以获取所有子项,而通过另一个请求,您可以获取所有父项,等等。
我认为你应该看看这个优秀的tree doctrine extensions以避免递归。如果你只在 doctrine 2.4,测试 2.3 扩展版本。
<?php
namespace Entity;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
/**
* @Gedmo\Tree(type="nested")
* @ORM\Table(name="categories")
* use repository for handy tree functions
* @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\NestedTreeRepository")
*/
class Category
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @ORM\Column(name="title", type="string", length=64)
*/
private $title;
/**
* @Gedmo\TreeLeft
* @ORM\Column(name="lft", type="integer")
*/
private $lft;
/**
* @Gedmo\TreeLevel
* @ORM\Column(name="lvl", type="integer")
*/
private $lvl;
/**
* @Gedmo\TreeRight
* @ORM\Column(name="rgt", type="integer")
*/
private $rgt;
/**
* @Gedmo\TreeRoot
* @ORM\ManyToOne(targetEntity="Category")
* @ORM\JoinColumn(name="tree_root", referencedColumnName="id", onDelete="CASCADE")
*/
private $root;
/**
* @Gedmo\TreeParent
* @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $parent;
/**
* @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
* @ORM\OrderBy({"lft" = "ASC"})
*/
private $children;
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
public function getRoot()
{
return $this->root;
}
public function setParent(Category $parent = null)
{
$this->parent = $parent;
}
public function getParent()
{
return $this->parent;
}
}
关于php递归函数性能优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56096663/