Jeg ville skrive ekskluderingstilslutningen uden underforespørgsler:
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;
Sørg for, at du har et indeks over produkter over de to kolonner (aktiv, produkt-id) i den rækkefølge.
Du bør også have et indeks over produkttags over de to kolonner (productid, tag) i den rækkefølge.
En anden forespørgsel, jeg bliver nødt til at gøre, er noget i stil med alle (Bil) eller (Skateboard) eller (Grøn OG Motorcykel) eller (Rød OG Motorcykel).
Nogle gange er disse komplekse forhold svære for MySQL-optimeringsværktøjet. En almindelig løsning er at bruge UNION til at kombinere enklere forespørgsler:
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:Din tagging-tabel er ikke en Entity-Attribute-Value-tabel.