2013-06-28 50 views
0

我知道這是一個相當普遍的問題,我相信答案很容易得到,但我不知道如何爲我的搜索詞組所以我一直不得不自己解決這個問題。MySQL - 我如何優化表b的追加字段到表a的查詢

表A

id | content_id | score 
1 | 2   | 16 
2 | 2   | 4 
3 | 3   | 8 
4 | 3   | 12 

表B

id | content 
1 | "Content Goes Here" 
2 | "Content Goes Here" 
3 | "Content Goes Here" 

目的: SUM從表A,組中的所有的分數由唯一的content_id,並顯示與該ID相關聯的內容,按總分排序。

當前工作查詢:

SELECT a.content_id, b.content, SUM(a.score) AS sum 
FROM table_a a 
LEFT JOIN table_b b ON a.content_id = b.id 
GROUP BY a.content_id 
ORDER BY sum ASC; 

問題:據我所知,與我已構建我的查詢方式,內容從表-B通過上表-A每個記錄循環抓起,使用相同的ID檢查table_b中的記錄,並抓取內容字段。這裏的問題是在table_a中有近500k +條記錄,而在table_b中有112條記錄。這意味着可能會執行潛在的500,000 x 112交叉表查找/匹配,僅將112個唯一內容字段附加到結果結果集中的總計112個結果中。

幫助!:如何更有效地將table_b中的112個內容字段追加到由查詢產生的112個結果中?我猜它與查詢執行順序有關,比如只是尋找並追加內容字段到匹配的結果行​​後產生的總和,它被縮小到只有112個記錄?研究過MySQL API並對各種子查詢,幾個連接進行了基準測試,甚至嘗試過使用UNION。這對你們來說可能是非常明顯的,但我的大腦無法繞過它。

供參考:就像前面提到的那樣,查詢確實有效。結果在大約8到10秒內生成,當然,由於查詢緩存,其後的每個後續查詢都立即生效。但對我來說,這是多麼簡單,我知道至少可以將8秒鐘減半。我只是覺得內心深處。在我的內心深處。

我希望這足夠簡潔,如果我需要澄清或解釋一些更好的東西,請讓我知道!提前致謝。

回答

2

MySQL查詢優化器只允許「nested loop joins」**這些是如何評估INNER連接的內部運算符。其他RDBMS允許其他類型的JOIN更高效。

但是,在你的情況下,你可以試試這個。希望優化器會做前總的JOIN

SELECT 
    a.content_id, b.content a.sum 
FROM 
    (
    SELECT content_id, SUM(score) AS sum 
    FROM table_a 
    GROUP BY content_id 
    ) a 
    JOIN table_b b ON a.content_id = b.id 
ORDER BY 
    sum ASC; 

此外,如果你不想要的結果排序,你可以使用ORDER BY NULL通常將刪除EXPLAIN一個filesort做。當然,我認爲有在2個content_id列(一個主鍵,一個外鍵索引)

最後索引,我也假設一個INNER JOIN就足夠了:每a.contentid存在於tableb。如果沒有,你缺少的a.contentid

外鍵和索引**這是越來越好,但you need MariaDBMySQL 5.6

+0

對思維相似,對於ORDER BY NULL優化:) – Stephan

+0

是啊!在你的情況下,內部的ORDER BY NULL可能會被忽略,因爲外部的一個控制它。其他的RDBMS不會允許內部的ORDER BY – gbn

+0

有趣...我不知道這一點...我假設,因爲首先完成聚合,將使用'ORDER BY NULL',然後當最終結果集爲獲得'ORDER BY asum'將被使用 – Stephan

1

這應該是快一點:

SELECT 
    tmp.content_id, 
    b.content, 
    tmp.asum 
FROM (
    SELECT 
     a.content_id, 
     SUM(a.score) AS asum 
    FROM 
     table_a a 
    GROUP BY 
     a.content_id 
    ORDER BY 
     NULL 
) as tmp 
LEFT JOIN table_b b 
    ON tmp.content_id = b.id 
ORDER BY 
    tmp.asum ASC 

您可以使用EXPLAIN檢查兩種查詢的查詢執行計劃,當你想對它們進行基準測試時

+0

我看到這與我接受的答案非常相似。我沒有測試過它,但我相信它比我的效率更高。感謝您花時間幫助我!對此,我真的非常感激。不得不接受他,只是因爲他更深入地解釋了爲什麼解決方案更高效。我會+1你,但我是一個stackoverflow newb。再次,謝謝! –