在SELECT中使用SELECT来减少查询数量是很常见的;但正如我所研究的那样,这会导致查询速度变慢(这显然不利于mysql的性能)。我有一个简单的查询,如下
SELECT something
FROM posts
WHERE id IN (
SELECT tag_map.id
FROM tag_map
INNER JOIN tags
ON tags.tag_id=tag_map.tag_id
WHERE tag IN ('tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6')
)这会导致“查询时间为3-4s;锁定时间约为0.000090s;检查了大约200行”的慢查询。
如果我拆分SELECT查询,每个查询都会非常快;但这会增加查询的数量,这不利于高并发。
是正常情况,还是我的代码出了什么问题?
发布于 2011-12-21 13:58:46
在MySQL中,像这样做一个子查询就是一个“相关查询”。这意味着外部SELECT的结果取决于内部SELECT的结果。结果是您的内部查询每行执行一次,这非常慢。
您应该重构这个查询;是连接两次还是使用两个查询几乎是无关紧要的。加入两次会给你带来:
SELECT something
FROM posts
INNER JOIN tag_map ON tag_map.id = posts.id
INNER JOIN tags ON tags.tag_id = tag_map.tag_id
WHERE tags.tag IN ('tag1', ...)有关更多信息,请参阅converting subqueries to JOINs上的MySQL手册。
提示:EXPLAIN SELECT将向您展示优化器计划如何处理查询。如果你看到DEPENDENT SUBQUERY,你应该重构,这些都是超级慢的。
发布于 2011-12-21 13:54:17
您可以通过使用以下命令来改进它:
SELECT something
FROM posts
INNER JOIN tag_map ON tag_map.id = posts.id
INNER JOIN tags
ON tags.tag_id=tag_map.tag_id
WHERE <tablename>.tag IN ('tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6')只需确保您只选择需要的内容,而不使用*;还要说明您在哪个表中有tag列,以便可以替换
发布于 2011-12-21 14:51:16
Join对结果进行过滤。第一个连接将使具有第一个条件的结果得到满足,然后第二个条件在第二个条件上给出最终结果。
SELECT something
FROM posts
INNER JOIN tag_map ON tag_map.id = posts.id
INNER JOIN tags ON tags.tag_id = tag_map.tag_id AND tags.tag IN ('tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6');你可以看到这些关于堆栈溢出的讨论:
Join有助于降低时间复杂度,提高服务器的稳定性。
将子查询转换为joins的信息:
https://stackoverflow.com/questions/8585592
复制相似问题