我目前的MySQL查询在我的应用程序中运行最多需要10秒钟:
SELECT tagid, tag FROM tags WHERE tagid IN
(SELECT DISTINCT tagid FROM news_tags WHERE newsid IN
(SELECT newsid FROM news_tags WHERE tagid IN (16,32)
GROUP BY newsid HAVING COUNT(newsid)>=2))
AND tagid NOT IN (16,32) ORDER BY level, tagid
使用的表是:
news_tags
,列newsid
,tagid
tags
,列tagid
,tag
,level
查询的目的是查找已使用tagid
16 和 32标记的“新闻”项目,然后查找其他标记这些新闻项目也已标记为,为了允许用户进一步缩小具有更具体标签组合的“新闻”项目。最终目标是从tag
表中获取剩余的相关tagid
和tags
列。
我尝试过等同JOIN
的不同尝试,但未能选择附加了提供标签的新闻项上的所有剩余tagid
。
这是我的EXPLAIN
SQL结果,如果它们指向另一个我不知道的缓慢原因:
id|select_type |table |type |possible_keys|key |key_len|ref |rows|Extra 1|PRIMARY |tags |range |PRIMARY |PRIMARY| 4|NULL| 55|Using where; Using filesort 2|DEPENDENT SUBQUERY|news_tags|index_subquery|tagid |tagid | 4|func| 26|Using index; Using where 3|DEPENDENT SUBQUERY|news_tags|index |tagid |PRIMARY| 8|NULL| 11|Using where; Using index
只是为了澄清问题:我希望剩下的标签用于标有BOTH标签16和32的新闻标签,而不是16或32.对不起任何混淆。
答案 0 :(得分:2)
SELECT DISTINCT tags.tagid, tags.tag
FROM
tags -- tags from the ...
JOIN news_tags AS n0 USING (tagid) -- ... news items tagged with ...
JOIN news_tags AS n1 USING (newsid) -- ... tagid = 16 and ...
JOIN news_tags AS n2 USING (newsid) -- ... tagid = 32
WHERE
n1.tagid = 16 AND n2.tagid = 32
AND tags.tagid NOT IN (16,32) -- not the tags we already know about
ORDER BY tags.level, tags.tagid
答案 1 :(得分:1)
编辑:我的查询严格基于提供的sql OP,只是试图像问题标题一样加快查询速度。
SELECT DISTINCT t.tagid, t.tag FROM tags AS t
JOIN news_tags AS nt1 USING (tagid)
JOIN news_tags AS nt2 USING (newsid)
WHERE nt2.tagid IN (16, 32) AND t.tagid NOT IN (16, 32)
GROUP BY nt2.newsid HAVING COUNT(nt2.newsid)>=2
ORDER BY t.level, t.tagid
答案 2 :(得分:0)
我最终提出了一个快速查询,使用JOINS而不是IN语句解决了这个问题:
SELECT tags.tagid,tags.tag FROM tags
INNER JOIN (SELECT DISTINCT news_tags.tagid FROM news_tags
INNER JOIN (SELECT newsid FROM news_tags WHERE tagid IN (16,32)
GROUP BY newsid HAVING count(newsid) >= 2) tagged_news
ON news_tags.newsid = tagged_news.newsid
WHERE news_tags.tagid NOT IN (16,32)) rem_tags
ON tags.tagid = rem_tags.tagid
ORDER BY level, tagid
这显然不像eggyal的解决方案那样干净或优雅,所以我最终在我的应用程序中采用了他的解决方案。
我希望听到更多客观原因(除了优雅)之外,为什么eggyval的解决方案会优先于上述SQL语句,既可以找到问题的最佳SQL语句,也可以学习将来。到目前为止,感谢所有帮助。