оптимизация производительности рекурсивной функции php - PullRequest
2 голосов
/ 12 мая 2019

Я использую Symfony 2.8 с доктриной 2.4

У меня есть объект с сопоставлением ассоциативных ссылок «один ко многим» entity: id name 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

Я написал функцию, которая находит идентификатор всех вложенных детей родителя.

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

Как я могу сократить время запроса?

Любая помощь будет высоко ценится!Спасибо

1 Ответ

0 голосов
/ 12 мая 2019

При реализации ваших детей у вас нет решения для эффективной оптимизации вашего кода.Вы должны изменить свою реализацию, чтобы пройти через всех ваших детей и подчиненных только с одним запросом.Древовидная реализация - лучшее решение, потому что с одним запросом SQL вы можете перехватить всех дочерних элементов, с другим запросом у вас могут быть все родители и т. Д.расширения , чтобы избежать рекурсии.Если вы используете только доктрину 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;
    }
}
...