我在我的网站上发现了一个性能问题。我有一个实体"购物车"与一对多关系。当我在一个提供大约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对象,它的订阅加载在内存中。