I have three tables, bookmarks, tag and tagging. tagging is the association table for linking tags to bookmarks. I would like to select related tags. The current query takes ages to run, but I could not wrap my head around the JOINs that could replace the subquery that selects all the related bookmarks that are tagged with specific tag IDs.
SELECT ta.name, count(*)
FROM tagging t2
JOIN tag ta ON t2.tag_id=ta.id
WHERE t2.bookmark_id IN (
SELECT bookmark_id
FROM tagging t1
WHERE t1.tag_id IN (1, 7)
GROUP BY t1.bookmark_id
HAVING COUNT(t1.id) = 2
)
GROUP BY ta.id
Here is the result of the EXPLAIN of that query:
1 PRIMARY ta index PRIMARY PRIMARY 8 NULL 3
1 PRIMARY t2 ref tag_id_idx tag_id_idx 8 blinkz.ta.id 89 Using where
2 DEPENDENT SUBQUERY t1 index tag_id_idx bookmark_id_idx 8 NULL 71 Using where
I have an index for the bookmark_id and tag_id fields in the tagging table. The tag table has a primary key named id
How could this query be optimised, preferably with a JOIN instead of a subquery?
The poor performance is due to a bug in MySQL that will hopefully be fixed soon. Until then try this instead:
I’m assuming that there is a unique contraint on
(bookmark_id, tag_id).