我不希望您在此Q上花费很多时间。但是,我感到在构建此查询时我犯了一个大错误并错过了一些东西。看起来像:
SELECT attributes, attributes_associations, COUNT(DISTINCT(products.id)) as count, attribute_groups, group_modifiers, linked_groups, linked_group_modifiers, attribute_linked_groups, attribute_category
FROM App\Component\Attribute\Entity\Attribute attributes
LEFT JOIN attributes.associations attributes_associations
INNER JOIN attributes.products products
LEFT JOIN attributes.group attribute_groups
LEFT JOIN attribute_groups.modifiers group_modifiers
LEFT JOIN attribute_groups.reverseLinkedGroups linked_groups
LEFT JOIN linked_groups.modifiers linked_group_modifiers
LEFT JOIN attributes.linkedGroups attribute_linked_groups
LEFT JOIN attribute_groups.attributeConditions attribute_groupsattribute_conditions
LEFT JOIN linked_groups.attributeConditions linked_groupsattribute_conditions
LEFT JOIN attribute_groups.groupConditions group_conditions
LEFT JOIN group_conditions.attributes group_conditions_attributes
LEFT JOIN group_conditions.linkedGroup group_linked_group_conditions
LEFT JOIN group_linked_group_conditions.attributes group_linked_group_conditions_attributes
LEFT JOIN linked_groups.groupConditions linked_group_conditions
LEFT JOIN linked_group_conditions.attributes linked_group_conditions_attributes
LEFT JOIN linked_group_conditions.linkedGroup reverse_linked_group_conditions
LEFT JOIN reverse_linked_group_conditions.attributes reverse_linked_group_conditions_attributes
LEFT JOIN attribute_groups.category attribute_category
LEFT JOIN attribute_linked_groups.category attribute_linked_category
LEFT JOIN linked_groups.category linked_category
WHERE attributes.isVisible = :attributeIsVisible AND products.isVisible = :productIsVisible
AND products.price > :priceMin AND products.price < :priceMax
AND (
(
(attribute_groupsattribute_conditions.id IN(:attributes) AND attribute_groups.conditionType = :conditionAnd)
OR ((attribute_groupsattribute_conditions.id IN(SELECT attribute_groupsattribute FROM App\Component\Attribute\Entity\Attribute attribute_groupsattribute
WHERE attribute_groupsattribute.id = :attribute_groups0 OR attribute_groupsattribute.id = :attribute_groups1 OR attribute_groupsattribute.id = :attribute_groups2 OR attribute_groupsattribute.id = :attribute_groups3 OR attribute_groupsattribute.id = :attribute_groups4 OR attribute_groupsattribute.id = :attribute_groups5))
AND attribute_groups.conditionType = :conditionOr))
OR attribute_groupsattribute_conditions IS NULL)
AND (((linked_groupsattribute_conditions.id IN(:attributes)
AND linked_groups.conditionType = :conditionAnd)
OR ((linked_groupsattribute_conditions.id IN(SELECT linked_groupsattribute
FROM App\Component\Attribute\Entity\Attribute linked_groupsattribute
WHERE linked_groupsattribute.id = :linked_groups0
OR linked_groupsattribute.id = :linked_groups1
OR linked_groupsattribute.id = :linked_groups2
OR linked_groupsattribute.id = :linked_groups3
OR linked_groupsattribute.id = :linked_groups4
OR linked_groupsattribute.id = :linked_groups5))
AND linked_groups.conditionType = :conditionOr)) OR linked_groupsattribute_conditions IS NULL)
AND (group_conditions_attributes.id IN(:attributes) OR group_conditions_attributes IS NULL)
AND (group_linked_group_conditions_attributes.id IN(:attributes) OR group_linked_group_conditions_attributes IS NULL)
AND (linked_group_conditions_attributes.id IN(:attributes) OR linked_group_conditions_attributes IS NULL)
AND (reverse_linked_group_conditions_attributes.id IN(:attributes) OR reverse_linked_group_conditions_attributes IS NULL)
AND (attribute_category.id = :attributeCategory OR attribute_linked_category.id = :attributeCategory OR linked_category.id = :attributeCategory)
AND (products.id IN(SELECT p40 FROM App\Component\Product\Entity\Product p40 INNER JOIN p40.attributes filters40 WHERE filters40 = 341 OR attribute_groups.id = :group40))
AND (products.id IN(SELECT p44 FROM App\Component\Product\Entity\Product p44 INNER JOIN p44.attributes filters44 WHERE filters44 = 374 OR attribute_groups.id = :group44))
AND (products.id IN(SELECT p76 FROM App\Component\Product\Entity\Product p76 INNER JOIN p76.attributes filters76 WHERE filters76 = 950 OR attribute_groups.id = :group76))
AND (products.id IN(SELECT p77 FROM App\Component\Product\Entity\Product p77 INNER JOIN p77.attributes filters77 WHERE filters77 = 952 OR attribute_groups.id = :group77))
AND products.id IN(SELECT product_department FROM App\Component\Product\Entity\Product product_department INNER JOIN product_department.attributes filters1002 WHERE filters1002.id = :filter1002)
GROUP BY attributes.id, attributes_associations.id, attribute_groups.id, group_modifiers.id, linked_groups.id, linked_group_modifiers.id, attribute_linked_groups.id, attribute_groupsattribute_conditions.id, linked_groupsattribute_conditions.id
ORDER BY count DESC, attributes.name ASC
这是一个按产品属性,属性组和属性类别进行过滤的查询。在没有失去其重要部分的情况下,我无法简化此查询。主要问题是运行此查询需要60秒钟。好吧,我的行数少于一百。我不能指望查询运行大约2分钟。
我需要Doctrine支持左连接,以便当我使用$attribute->getGroup()
时不会进行新查询。此外,在某些情况下我无法避免左联接,因为联接表上有条件。
我找到了这篇文章https://www.colinodell.com/blog/201703/limiting-subqueries-doctrine-2-dql。但是仅在join子查询中仅选择一行时才有效。而且,Doctrine不会将子查询的结果用作适当的实体关系。
如果我错过了一些细节,请告诉我。