我有3个模型使用单表继承.它们适用于可在我们网站上购买的三种不同类型的物品.这些项目被分类,因此Category模型具有用于映射这三种类型中的每一种的属性.
当使用简单的选择来获取所有类别,然后显示其名称和类别中每种类型的项目的数量时,Doctrine总共执行369个查询,总共549毫秒. (一个用于类别列表,然后一个用于类别中的每个类型.)
所以我开始在查询中添加联接以消除所有额外的查询.它适用于第一个项目类型,主查询运行在101.80毫秒. (根据Symfony Profiler工具栏)
$this->_em->createQueryBuilder() ->select([$alias,'courses']) ->from($this->_entityName,$alias) ->leftJoin("{$alias}.courses",'courses');
$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;
对象和属性与行和列之间的区别在这里无关紧要.
原文链接:https://www.f2er.com/php/136978.html您正在尝试进行一系列LEFT JOIN,您可能应该使用UNION.
请参阅CROSS JOIN和笛卡儿产品上的Microsoft’s take.他们真的总结得很好.
编辑:我认为这回答了“为什么我的第二次加入缓慢?”的问题.
您的意思是:“请帮助我改进我的3模型Doctrine查询,以便在不到550毫秒的时间内运行.” ?