我在网站上发现了性能问题。 我有一个实体" Cart"与oneToMany关系。当我在一个提供大约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;
}
我的twig视图调用getSubscriptions()产生大量数据库请求:
{% for subscription in cart.subscriptions %}
我能做些什么才能获得更好的表现?
答案 0 :(得分:1)
您遇到的问题称为N + 1问题。您正在获取一个具有关联的实体,然后您可以遍历该实体并再次查询。在您的具体示例中,这发生在此循环中,假设您的订阅具有成本:
{% for subscription in cart.subscriptions %}
{{ subscription.cost }}
鉴于您已经查询过购物车,您尚未加载所有订阅及其属性,而且这些订阅及其属性在循环时发生。要解决这个问题,您应该在购物车上fetch join进行订阅:
// 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对象,并将其订阅加载到内存中。