[英]Subselect in WHERE or FROM clause?
如果特定的子選擇(子查詢)位於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;
查詢 WHERE
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);
在這兩種情況下, 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 ... )
是有益的。 (但我在你的情況下沒有看到這種情況。
你的問題是關於一般優化。 我想強調的是,沒有普遍的答案。
我認為這個請求比你上面給出的要快,因為它沒有子查詢。
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.