Jes*_*ica 9 php mysql single-table-inheritance symfony doctrine-orm
我有3个模型使用单表继承.它们适用于可在我们网站上购买的三种不同类型的商品.这些项目被分类,因此Category模型具有用于映射这三种类型中的每一种的属性.
当使用简单的选择来获取所有类别,然后在类别中显示它们的名称和每种类型的项目的数量时,Doctrine总共执行369个查询,总共549毫秒.(一个用于类别列表,然后一个用于类别中的每个类型.)
所以我开始在查询中添加联接以消除所有额外的查询.它适用于第一个项目类型,主查询运行在101.80毫秒.(根据Symfony Profiler工具栏)
$this->_em->createQueryBuilder()
->select([$alias, 'courses'])
->from($this->_entityName, $alias)
->leftJoin("{$alias}.courses", 'courses');
Run Code Online (Sandbox Code Playgroud)
只要我添加第二个连接,查询就会减慢到24050.14毫秒
$qb = $this->_em->createQueryBuilder()
->select([$alias, 'courses', 'bundles'])
->from($this->_entityName, $alias)
->leftJoin("{$alias}.courses", 'courses')
->leftJoin("{$alias}.bundles", 'bundles');
Run Code Online (Sandbox Code Playgroud)
我还没有尝试过第三次加入,担心它会让服务器崩溃.
真正奇怪的是,如果我使用Doctrine查询记录并获得确切的查询,并在我的数据库上手动运行它,它只运行0.2秒.
该表在所有FK列和鉴别器列上都有索引.
任何建议将不胜感激.谢谢!
编辑:4/3
我必须让分支回到其他问题的工作点才能回到这个问题.
SQL小提琴与架构(减去其他未在这种情况下加载的表的FK):http://sqlfiddle.com/#!28/85051
所以,我有没有连接的页面,并且它在820.38毫秒内进行了382次查询以进行延迟加载.当我手动加入,而不是依赖延迟加载,它以130为21159(这是唯一加盟模式2,所以它仍然懒加载第三)
$qb = $this->_em->createQueryBuilder()
->select([$alias, 'courses', 'bundles'])
->from($this->_entityName, $alias)
->leftJoin("{$alias}.courses", 'courses')
->leftJoin("{$alias}.bundles", 'bundles');
Run Code Online (Sandbox Code Playgroud)
这是来自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
Run Code Online (Sandbox Code Playgroud)
并解释它:
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
Run Code Online (Sandbox Code Playgroud)
*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;
Run Code Online (Sandbox Code Playgroud)
和类别模型上的映射
/**
* @var ArrayCollection
*
* @ORM\ManyToMany(targetEntity="models\Course")
* @ORM\JoinTable(name="item_category_assignment",
* inverseJoinColumns={@ORM\JoinColumn(name="item_id", referencedColumnName="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",
* inverseJoinColumns={@ORM\JoinColumn(name="item_id", referencedColumnName="id")},
* joinColumns={@ORM\JoinColumn(name="item_category_id", referencedColumnName="id")}
* )
*/
protected $bundles;
/**
* @var ArrayCollection
*
* @ORM\ManyToMany(targetEntity="models\Package", mappedBy="categories", orphanRemoval=true)
* @ORM\JoinTable(name="item_category_assignment",
* inverseJoinColumns={@ORM\JoinColumn(name="item_id", referencedColumnName="id")},
* joinColumns={@ORM\JoinColumn(name="item_category_id", referencedColumnName="id")}
* )
*/
protected $packages;
Run Code Online (Sandbox Code Playgroud)