你可以這樣使用重寫加入,MySQL在已知問題的子查詢,尤其是對於大型數據集時:
SELECT n.*,
`id` as `newscode`,
COALESCE(l.TotalLikes, 0) AS `total_likes`,
COALESCE(c.TotalComments, 0) AS `total_comments`
FROM `news` n
LEFT JOIN
( SELECT Code, COUNT(*) AS TotalLikes
FROM `likes`
WHERE `type` = "newspost"
GROUP BY Code
) AS l
ON l.`code` = n.`id`
LEFT JOIN
( SELECT post_id, COUNT(*) AS TotalComments
FROM `news_comments`
GROUP BY post_id
) AS c
ON c.`post_id` = n.`id`
ORDER BY n.`id` DESC LIMIT 5;
的原因是,當您使用如上聯接,MySQL將物化的結果當第一次需要它的子查詢,如在此查詢的開始,MySQL將投入的結果:
SELECT post_id, COUNT(*) AS TotalComments
FROM `news_comments`
GROUP BY post_id
到存儲表和哈希POST_ID更快的查找。然後,對於news
中的每一行,只需從該散列表中查找TotalComments
,當您使用相關子查詢時,它將爲news
中的每一行執行一次查詢,當news
較大時將導致大量執行。如果初始結果集很小,您可能看不到性能優勢,並且可能會更糟。在SQL小提琴
最後
例子,你可能想指數news_comments
和likes
相關領域。對於這個特定的查詢我認爲以下指標將幫助:
CREATE INDEX IX_Likes_Code_Type ON Likes (Code, Type);
CREATE INDEX IX_newcomments_post_id ON news_comments (post_id);
雖然你可能需要將第一指數分爲兩個:
CREATE INDEX IX_Likes_Code ON Likes (Code);
CREATE INDEX IX_Likes_Type ON Likes (Type);
當運行這個時,我在'on clause'中得到錯誤'未知列'n.newscode'。 – user3205106
你是什麼意思?有單獨的表格。 – user3205106
在獲取'total_likes'的子查詢中,您在WHERE子句中使用了這個:'\'code \'= \'newscode \''。 'newscode'在這裏指的是什麼?我知道他們是獨立的桌子,但大概他們有聯繫?否則,你只是得到喜歡的總數,除非有關係,否則對每一行都是相同的。 – GarethD