Napsal bych spojení vyloučení bez poddotazů:
SELECT p.productid
FROM products p
INNER JOIN producttags AS t ON p.productid = t.productid
LEFT OUTER JOIN producttags AS x ON p.productid = x.productid
AND x.tag IN ('Motorcycle', 'Green')
WHERE p.active = 1
AND t.tag IN ( 'Ford', 'Black', 'Skateboard' )
AND x.productid IS NULL;
Ujistěte se, že máte index produktů ve dvou sloupcích (active, productid) v tomto pořadí.
Měli byste také mít index na producttags přes dva sloupce (productid, tag) v tomto pořadí.
Další dotaz, který budu muset udělat, je něco jako vše (Auto) nebo (Skateboard) nebo (Zelená A Motocykl) nebo (Červená A Motocykl).
Někdy jsou tyto složité podmínky pro optimalizátor MySQL obtížné. Jedním z běžných řešení je použití UNION ke kombinaci jednodušších dotazů:
SELECT p.productid
FROM products p
INNER JOIN producttags AS t1 ON p.productid = t1.productid
WHERE p.active = 1
AND t1.tag IN ('Car', 'Skateboard')
UNION ALL
SELECT p.productid
FROM products p
INNER JOIN producttags AS t1 ON p.productid = t1.productid
INNER JOIN producttags AS t2 ON p.productid = t2.productid
WHERE p.active = 1
AND t1.tag IN ('Motorcycle')
AND t2.tag IN ('Green', 'Red');
PS:Vaše tabulka značek není tabulka Entity-Attribute-Value.