Mysql 在WHERE或FROM子句中进行子选择?
我想知道如果特定的subselect(subquery)位于Mysql 在WHERE或FROM子句中进行子选择?,mysql,sql,query-optimization,Mysql,Sql,Query Optimization,我想知道如果特定的subselect(subquery)位于WHERE或FROM子句中,查询的一般性能如何。我没有找到足够的解释哪种方式更好。在这种查询中,我们应该如何应用subselect有一些规则吗 我准备了下面的例子 来自的查询 SELECT name FROM users a JOIN (SELECT user_id, AVG(score) as score FROM scores GROUP BY user_id ) b O
WHERE
或FROM
子句中,查询的一般性能如何。我没有找到足够的解释哪种方式更好。在这种查询中,我们应该如何应用subselect有一些规则吗
我准备了下面的例子
来自的查询
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),
(2, 10),
(3, 20),
(3, 18),
(4, 13),
(4, 16),
(4, 15);
在这两种情况下,
分数
需要索引(用户id,分数)
来提高性能
很难预测哪个会跑得更快
有时,类似于第一个公式的查询非常出色。这是因为它会离开一个专注于b
的窗口,并一次有效地计算所有平均值。然后它到达另一个表以获取最终信息
让我们稍微调整一下第二个版本,在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的交换不是优化;它只是显示优化器执行步骤的顺序。)
在其他一些情况下,存在(选择…
是有益的。(但在你的情况下,我看不到这种情况
你的问题是关于一般优化的。我想强调的是没有一般的答案。我认为这个请求比你上面给出的更快,因为它没有子查询
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
您可以在此链接上看到:
它显示了接下来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
您使用的是哪种dbms?您比较过解释/执行计划吗?通常是mysql,但它是否依赖于dbms?尝试运行这两个查询,并选择一个对您的系统和数据最有效的查询。因为
其中b.score…
,LEFT
不相关。请删除它。我认为在第二个查询中,我们每个人都会计算AVG呃,分开来说,它应该会慢一些。但是后来我看到一些数据库管理系统优化了这种查询,一次计算了所有的查询,我想知道这个技巧的优势在哪里。谢谢。我认为这是一个简单的问题。只需知道MySQL是如何工作的。@Tajni-一些简单的问题有简单的答案,一些没有。s由于MySQL不断发展,一些答案会随着时间的推移而改变。MySQL 4.0(20年前)中不存在子查询。5.6在这方面添加了一些显著的性能增强。等等。