如何解决在WHERE或FROM子句中进行子选择?
我想知道查询的一般性能,如果特定的子查询(子查询)位于WHERE
或FROM
子句中。我没有找到足够的解释哪种方法更好。是否有一些规则应如何在这种查询中应用子选择?
我准备了以下示例
查询自
SELECT name
FROM users a
JOIN (SELECT user_id,AVG(score) as score
FROM scores GROUP BY user_id
) b ON a.id=b.user_id
WHERE b.score > 15;
查询位置
SELECT name
FROM users
WHERE
(SELECT AVG(score) as score
FROM scores WHERE scores.user_id=users.id GROUP BY user_id
) > 15;
表格:
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(30));
CREATE TABLE scores (
id INT PRIMARY KEY AUTO_INCREMENT,user_id INT,score INT);
INSERT INTO users(name)
VALUES ('John'),('Max'),('Dan'),('Alex');
INSERT INTO scores(user_id,score)
VALUES
(1,20),(1,19),(2,15),10),(3,18),(4,13),16),15);
解决方法
在两种情况下,scores
都需要INDEX(user_id,score)
来提高性能。
很难预测哪个将运行得更快。
有时与第一个表述类似的查询是非常好的。这是因为它专注于b
,并且可以一次高效地计算所有AVG。然后到达另一个表以获取最终信息。
我们通过在WHERE
子句中添加其他测试来稍微调整第二个版本。现在第二个可能更快。
这可能更好:
SELECT name
FROM ( SELECT user_id -- Don't fetch AVG if not needed
FROM scores GROUP BY user_id
HAVING AVG(score) > 15; -- Note
) b
JOIN users a ON a.id = b.user_id
(FROM和JOIN的交换不是优化,只是为了显示优化器将按什么顺序执行这些步骤。)
在其他情况下,EXISTS( SELECT ... )
是有益的。 (但在您的情况下我看不到。
您的问题是关于一般优化的。我想强调的是,没有 general 答案。
,我认为此请求比您上面的请求要快,因为它没有子查询。
SELECT u.name
FROM users u
JOIN scores s
ON (s.user_id = u.id)
GROUP BY s.user_id
HAVING AVG(s.score) > 15
您可以在以下链接上看到它:http://sqlfiddle.com/#!9/b050f9/16 它显示了接下来的3个Select查询的执行时间:
SELECT name
FROM users a
JOIN (SELECT user_id,AVG(score) as score
FROM scores GROUP BY user_id
) b ON a.id=b.user_id
WHERE b.score > 15;
SELECT name
FROM users
WHERE
(SELECT AVG(score) as score
FROM scores WHERE scores.user_id=users.id GROUP BY user_id
) > 15;
SELECT u.name
FROM users u
JOIN scores s
ON (s.user_id = u.id)
GROUP BY s.user_id
HAVING AVG(s.score) > 15
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。