php – Doctrine加入两个具有单表继承的模型,第二个连接减慢速度

前端之家收集整理的这篇文章主要介绍了php – Doctrine加入两个具有单表继承的模型,第二个连接减慢速度前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有3个模型使用单表继承.它们适用于可在我们网站上购买的三种不同类型的物品.这些项目被分类,因此Category模型具有用于映射这三种类型中的每一种的属性.

当使用简单的选择来获取所有类别,然后显示名称和类别中每种类型的项目的数量时,Doctrine总共执行369个查询,总共549毫秒. (一个用于类别列表,然后一个用于类别中的每个类型.)

所以我开始在查询添加联接以消除所有额外的查询.它适用于第一个项目类型,主查询运行在101.80毫秒. (根据Symfony Profiler工具栏)

$this->_em->createQueryBuilder()
        ->select([$alias,'courses'])
        ->from($this->_entityName,$alias)
        ->leftJoin("{$alias}.courses",'courses');

只要我添加第二个连接,查询就会减慢到24050.14毫秒

$qb = $this->_em->createQueryBuilder()
        ->select([$alias,'courses','bundles'])
        ->from($this->_entityName,'courses')
        ->leftJoin("{$alias}.bundles",'bundles');

我还没有尝试过第三次加入,担心它会让服务器崩溃.

真正奇怪的是,如果我使用Doctrine查询记录并获得确切的查询,并在我的数据库上手动运行它,它只运行0.2秒.

该表在所有FK列和鉴别器列上都有索引.

任何建议将不胜感激.谢谢!

编辑:4/3

我必须让分支回到其他问题的工作点才能回到这个问题.

sql Fli with Schema(减去在这种情况下未加载的其他表的FK):http://sqlfiddle.com/#!2/85051

所以,我有没有连接的页面,并且它在820.38毫秒内进行了382次查询以进行延迟加载.当我手动加入而不是依赖于延迟加载时,它确实是130是21159(这只加入了2个模型,所以它仍然懒得加载第三个)

$qb = $this->_em->createQueryBuilder()
        ->select([$alias,'bundles');

这是来自Symfony工具栏的查询(20241.26 ms)

SELECT 
  i0_.description AS description0,i0_.id AS id1,i0_.name AS name2,i0_.created_at AS created_at3,i0_.updated_at AS updated_at4,i0_.display_order AS display_order5,i1_.atccode AS atccode6,i1_.version AS version7,i1_.description AS description8,i1_.online_price AS online_price9,i1_.mail_price AS mail_price10,i1_.is_featured AS is_featured11,i1_.code AS code12,i1_.hours AS hours13,i1_.summary AS summary14,i1_.SEO_keywords AS SEO_keywords15,i1_.SEO_description AS SEO_description16,i1_.asha_code AS asha_code17,i1_.preview_name AS preview_name18,i1_.preview_link AS preview_link19,i1_.preview_type AS preview_type20,i1_.is_active AS is_active21,i1_.id AS id22,i1_.name AS name23,i1_.created_at AS created_at24,i1_.updated_at AS updated_at25,i1_.deleted_at AS deleted_at26,i1_.goals AS goals27,i1_.disclosure_statement AS disclosure_statement28,i1_.embedded_video AS embedded_video29,i1_.broadcast_chat_link AS broadcast_chat_link30,i2_.atccode AS atccode31,i2_.version AS version32,i2_.description AS description33,i2_.online_price AS online_price34,i2_.mail_price AS mail_price35,i2_.is_featured AS is_featured36,i2_.code AS code37,i2_.hours AS hours38,i2_.summary AS summary39,i2_.SEO_keywords AS SEO_keywords40,i2_.SEO_description AS SEO_description41,i2_.asha_code AS asha_code42,i2_.preview_name AS preview_name43,i2_.preview_link AS preview_link44,i2_.preview_type AS preview_type45,i2_.is_active AS is_active46,i2_.id AS id47,i2_.name AS name48,i2_.created_at AS created_at49,i2_.updated_at AS updated_at50,i2_.deleted_at AS deleted_at51,i0_.created_by AS created_by52,i0_.updated_by AS updated_by53,i1_.type AS type54,i1_.item_format_id AS item_format_id55,i1_.company_id AS company_id56,i1_.created_by AS created_by57,i1_.updated_by AS updated_by58,i1_.format_video_id AS format_video_id59,i1_.exam_id AS exam_id60,i1_.survey_id AS survey_id61,i1_.royalty_owner_id AS royalty_owner_id62,i2_.type AS type63,i2_.item_format_id AS item_format_id64,i2_.company_id AS company_id65,i2_.created_by AS created_by66,i2_.updated_by AS updated_by67 
FROM 
  item_category i0_ 
  LEFT JOIN item_category_assignment i3_ ON i0_.id = i3_.item_category_id 
  LEFT JOIN item i1_ ON i1_.id = i3_.item_id 
  AND i1_.type IN ('Product') 
  AND (
    (
      i1_.deleted_at IS NULL 
      OR i1_.deleted_at > '2014-04-03 13:50:45'
    )
  ) 
  LEFT JOIN item_category_assignment i4_ ON i0_.id = i4_.item_category_id 
  LEFT JOIN item i2_ ON i2_.id = i4_.item_id 
  AND i2_.type IN ('Bundle') 
  AND (
    (
      i2_.deleted_at IS NULL 
      OR i2_.deleted_at > '2014-04-03 13:50:45'
    )
  ) 
WHERE 
  i0_.id IN (
    '108','175','100','202','198','203','199','200','201','197','101','98','102','131','105','41','72','64','73','194','195','29','189','139','103','37','99','14','110','193','80','111','68','183','39','71','53','66','178','179','180','176','174','75','17','32','81','181','182','74','104','184','26','49','190','191','36','24','85','30','107','91','90','185','23','196','60','89','21','95','65','28','33','58','187','9','132','12','43','192','5','62','40','87','7','83','27','6','86','10','13','15','70','69','121','67','93','97','92','94','188','177','82','96','42','137','19','11','63','20','51','57','8','22','48','35','4','135','61','186','106','109','88','16','31','34'
  ) 
ORDER BY 
  i0_.name ASC

并解释它:

1   SIMPLE       i0_    ALL     PRIMARY                                                                       126   Using where; Using filesort,1   SIMPLE       i3_    ref     item_category_id         item_category_id  4        cems-staging.i0_.id       6,1   SIMPLE       i1_    eq_ref  PRIMARY                    PRIMARY           4        cems-staging.i3_.item_id  1     Using where,1   SIMPLE       i4_    ref     item_category_id         item_category_id  4        cems-staging.i0_.id       6,1   SIMPLE       i2_    eq_ref  PRIMARY                    PRIMARY           4        cems-staging.i4_.item_id  1     Using where

* PHP *

这是Items模型的映射:

/**
 * @var ArrayCollection
 * @ORM\ManyToMany(targetEntity="models\Category")
 * @ORM\JoinTable(name="item_category_assignment",*    joinColumns={@ORM\JoinColumn(name="item_id",referencedColumnName="id")},*    inverseJoinColumns={@ORM\JoinColumn(name="item_category_id",referencedColumnName="id")}
 * )
 */
protected $categories;

和类别模型上的映射

/**
 * @var ArrayCollection
 *
 * @ORM\ManyToMany(targetEntity="models\Course")
 * @ORM\JoinTable(name="item_category_assignment",*    inverseJoinColumns={@ORM\JoinColumn(name="item_id",*    joinColumns={@ORM\JoinColumn(name="item_category_id",referencedColumnName="id")}
 * )
 */
protected $courses;

/**
 * @var ArrayCollection
 *
 * @ORM\ManyToMany(targetEntity="models\Bundle",mappedBy="categories",orphanRemoval=true)
 * @ORM\JoinTable(name="item_category_assignment",referencedColumnName="id")}
 * )
 */
protected $bundles;

/**
 * @var ArrayCollection
 *
 * @ORM\ManyToMany(targetEntity="models\Package",referencedColumnName="id")}
 * )
 */
protected $packages;
对象和属性与行和列之间的区别在这里无关紧要.

您正在尝试进行一系列LEFT JOIN,您可能应该使用UNION.

请参阅CROSS JOIN和笛卡儿产品上的Microsoft’s take.他们真的总结得很好.

编辑:我认为这回答了“为什么我的第二次加入缓慢?”的问题.

您的意思是:“请帮助我改进我的3模型Doctrine查询,以便在不到550毫秒的时间内运行.” ?

猜你在找的PHP相关文章