在 mysql 查询中的 SELECT 中使用 SELECT
Posted
技术标签:
【中文标题】在 mysql 查询中的 SELECT 中使用 SELECT【英文标题】:Using SELECT within SELECT in mysql query 【发布时间】:2012-01-25 00:22:07 【问题描述】:在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-4 秒;锁定时间大约 0.000090 秒;检查大约 200 行”的慢查询。
如果我拆分SELECT
查询,每个查询都会很快;但是这样会增加不擅长高并发的查询。
这是正常情况,还是我的编码有问题?
【问题讨论】:
SELECT
在SELECT
内?!这就像那部电影......选择。
【参考方案1】:
在 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
你应该重构,这些速度非常慢。
【讨论】:
【参考方案2】:您可以使用以下方法对其进行改进:
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')
只要确保你只选择你需要的,不要使用 *;还要说明您在哪个表中有标签列,以便您可以替换
【讨论】:
这就是我们所说的JOIN。 是的,内连接两次,至少我认为它比 in 子句快【参考方案3】:Join 过滤结果。第一次加入将保持满足第一个 ON 条件的结果,然后第二个条件在第二个 ON 条件下给出最终结果。
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');
你可以看到这些关于堆栈溢出的讨论:
question1 question2
加入有助于降低时间复杂度并提高服务器的稳定性。
将子查询转换为连接的信息:
link1 link2 link3
【讨论】:
以上是关于在 mysql 查询中的 SELECT 中使用 SELECT的主要内容,如果未能解决你的问题,请参考以下文章