Symfony 2 OneToMany性能优化


Symfony 2 OneToMany performance optimisation

我在我的网站上发现了一个性能问题。我有一个实体"购物车"与一对多关系。当我在一个提供大约2000个查询的视图中调用getter方法时。然后页面的性能急剧下降。

我的实体购物车与OneTMany assoc:

class Cart {
    /**
     * @ORM'OneToMany(targetEntity="Comiti'UserBundle'Entity'Subscription", mappedBy="cart")
     */
    protected $subscriptions;
}

我的实体订阅ManyToOne assoc:

class Subscription {
    /**
     * @ORM'ManyToOne(targetEntity="Comiti'UserBundle'Entity'Cart",inversedBy="subscriptions")
     * @ORM'JoinColumn(name="cart_id", referencedColumnName="id")
     * @JMS'Exclude()
     */
    protected $cart;
}

调用getSubscriptions()生成大量数据库请求的我的小树枝视图:

{% for subscription in cart.subscriptions %}

我能做些什么来获得更好的表现?

您遇到的问题称为N+1问题。您正在获取一个具有关联的实体,然后遍历并再次查询该实体。在您的具体示例中,这发生在这个循环中,假设您的订阅有成本:

{% for subscription in cart.subscriptions %}
    {{ subscription.cost }}

假设你已经查询了一个购物车,你还没有加载它的所有订阅和属性,这是在循环时发生的。为了解决这个问题,你应该在你的购物车上加入订阅:

// in CartRepository
public function findCartWithSubscriptions($cartId)
{
    $qb = $this->createQueryBuilder('c');
    $qb->leftJoin('c.subscriptions', 's')
    ->where("c = :cart")
    ->setParameter("cart", $cartId);
    return $qb->getQuery()->getResult();
}

这将为您水合一个Cart对象,它的订阅加载在内存中。