我有三个表,bookmarks
,tag
和tagging
。 tagging
是用于将标记链接到书签的关联表。我想选择相关的标签。当前查询需要花费很长时间才能运行,但我无法绕过可能替换选择所有标记有特定标记ID的相关书签的子查询的JOIN。
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
以下是该查询的EXPLAIN
的结果:
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
我有bookmark_id
表中tag_id
和tagging
字段的索引。 tag
表有一个名为id
如何优化此查询,最好使用JOIN而不是子查询?
答案 0 :(得分:2)
表现不佳是因为bug in MySQL很快就会被修复。在那之前尝试这个:
SELECT tag.name, COUNT(*) AS cnt
FROM tagging T1
JOIN tag
ON T1.tag_id = tag.id
JOIN (
SELECT bookmark_id
FROM tagging
WHERE tag_id IN (1, 7)
GROUP BY bookmark_id
HAVING COUNT(id) = 2
) T2
ON T1.bookmark_id = T2.bookmark_id
GROUP BY tag.id
我假设(bookmark_id, tag_id)
上有一个独特的约束。