Toto je případ relačního rozdělení:
SELECT c.id, c.name
FROM components_componentproperty cp1
JOIN components_componentproperty cp2 USING (component_id)
JOIN components_component c ON c.id = cp1.component_id
WHERE cp1.property_id = 9102 AND cp1.value IN ('4015', '4016')
AND cp2.property_id = 8801 AND cp2.value = '3'
AND c.type_id = 3832
GROUP BY c.id;
Zde jsme shromáždili arzenál příslušných technik:
Zkontrolujte velký počet vlastností
Výše uvedený dotaz můžete rozšířit a pro ruku plnou vlastností bude patřit mezi nejrychlejší možná řešení. Pro větší počet bude pohodlnější (a také začíná být rychlejší) jít touto cestou:
Příklad pro 5 vlastností, rozbalte podle potřeby:
SELECT c.id, c.name
FROM (
SELECT id
FROM (
SELECT component_id AS id, property_id -- alias id just to shorten syntax
FROM components_componentproperty
WHERE property_id IN (9102, 8801, 1234, 5678, 9876) -- expand as needed
GROUP BY 1,2
) cp1
GROUP BY 1
HAVING count(*) = 5 -- match IN expression
) cp2
JOIN components_component c USING (id);
Další krok vnitřního poddotazu cp1
je pouze nezbytné, protože zjevně máte více položek na (component_id, property_id)
v components_componentproperty
. Mohli fold cp1
a cp2
do jednoho a zkontrolujte
HAVING count(DISTINCT property_id) = 5
Ale očekávám, že to bude dražší, protože count(DISTINCT col)
potřebuje jednu operaci řazení na řádek .
Pro velmi dlouhé seznamy IN
je špatná volba. Zvažte: