[英]Turn a Mysql Subquery in a Join
如何在JOIN
轉換此子查詢?
我讀到子查詢比JOIN
慢。
SELECT
reklamation.id,
reklamation.titel,
(
SELECT reklamation_status.status
FROM reklamation_status
WHERE reklamation_status.id_reklamation = reklamation.id
ORDER BY reklamation_status.id DESC
LIMIT 1
) as status
FROM reklamation
WHERE reklamation.aktiv=1
使用JOIN
查詢可以重寫為:
SELECT reklamation.id, reklamation.titel, reklamation_status.status
FROM reklamation
JOIN reklamation_status ON reklamation_status.id_reklamation = reklamation.id
WHERE reklamation.aktiv=1
這應該這樣做:
SELECT r.id, r.titel, MAX(s.id) as status
FROM reklamation r
LEFT JOIN reklamation_status s ON s.id_reklamation = r.id
WHERE r.aktiv = 1
GROUP BY r.id, r.titel
這里的關鍵點是使用聚合來管理reklamation
和reklamation_status
之間的基數。 在原始代碼中,內聯子查詢使用ORDER BY reklamation_status.id DESC LIMIT 1
返回reklamation_status
中與當前reklamation
對應的最高id
。 如果沒有聚合,我們可能會在結果reklamation
為每個reklamation
獲取多個記錄(每個對應的reklamation_status
)。
另一件事是考慮是JOIN
的類型。 INNER JOIN
會過濾掉的記錄reklamation
沒有A S reklamation_status
:與內聯子查詢的原始查詢不那樣做,所以我選擇了LEFT JOIN
。 如果您可以保證每個reklamation
在reklamation
中至少有一個子reklamation_status
,則可以安全地切換回INNER JOIN
(可能更有效地執行)。
PS:
我讀到子查詢比
JOIN
慢。
這不是一個普遍的事實。 這取決於很多因素,如果沒有看到確切的用例,就無法告知。
你讀的是不正確的。 子查詢可以更慢,更快或與聯接相同。 我會把查詢寫成:
SELECT r.id, r.titel,
(SELECT rs.status
FROM reklamation_status rs
WHERE rs.id_reklamation = r.id
ORDER BY rs.id DESC
LIMIT 1
) as status
FROM reklamation r
WHERE r.aktiv = 1;
為了提高性能,您需要reklamation_status(id_reklamation, id, status)
的索引。
順便說一下,這是子查詢可能是表達此查詢的最快方法的情況。 如果您嘗試JOIN
,則需要某種聚合來獲取最新狀態。 這可能很昂貴。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.