Я не хочу, чтобы вы тратили много времени на этот вопрос. Однако я чувствую, что допустил большую ошибку и что-то упустил при создании этого запроса. Похоже:
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. Но это работает, только если выбрать только одну строку в подзапросе соединения. Более того, Doctrine не будет использовать результат подзапроса как правильные отношения сущностей.
Если я пропустил некоторые детали, дайте мне знать.