2014-07-10 30 views
0

我有這個查詢(下),而它的工作,我想知道它是否是最好的,因爲它將違背數千記錄。我會盡力解釋我能做到的最好。寫這個查詢的最佳方法是什麼?幾個聯接

SELECT items.*, 
     p.file      AS item_pic, 
     i_f.id      AS favorite_id, 
     COALESCE(f.favorite_count, 0) AS favorite_count, 
     COALESCE(b.num_buys, 0)  AS num_buys, 
     COALESCE(c.comment_count, 0) AS comment_count 
FROM items i 
     INNER JOIN (SELECT file, 
          item_id 
        FROM item_pics 
        ORDER BY item_pics.id ASC) AS p 
       ON p.item_id = i.id 
     LEFT JOIN (SELECT COUNT(*) AS favorite_count, 
         item_id 
        FROM item_favorites 
        GROUP BY item_id) AS f 
       ON f.item_id = i.id 
     LEFT JOIN (SELECT COUNT(*) AS num_buys, 
         item_id 
        FROM purchases 
        GROUP BY item_id) AS b 
       ON b.item_id = i.id 
     LEFT JOIN (SELECT COUNT(*) AS comment_count, 
         item_id 
        FROM comments 
        GROUP BY item_id) AS c 
       ON c.item_id = i.id 
     LEFT JOIN item_favorites AS i_f 
       ON i.id = i_f.item_id 
       AND i_f.userid = '14' 
GROUP BY i.id 
LIMIT 0, 20 

所以我們選擇數據庫中的項目。第一次加入是爲了一張照片(項目有多張照片,但我只想要一張)。

下加入是最喜歡的計數。每次用戶最喜歡的東西都會將其添加到表格收藏中,並提供一些信息,所以我只是想獲得該物品的收藏總數。

接下來是購買該項目的數量。幾乎與收藏夾一樣。

之後,它是徵求意見。再次,這就像購買和收藏數量。

最後的聯接是看是否登錄的用戶(ID 14),如果不是我用COALESCE返回0。

就像我所說的這一切工作正常已收藏了此項目,但它確實需要幾秒鐘加載約6700個項目和約180K行的表格上,每次只加載20個表格(我做了類似於Facebook/Twitter的滾動/加載)。索引已在所有表上正確設置。一旦這是完整/正確的,我想知道如何限制在過去七天購買的結果和購買數量(num_buys)的順序。

編輯:從結果可以解釋

enter image description here

+1

我會做的第一件事就是爲每個表添加一個別名並適當地使用別名......這將使讀取查詢和加速幫助過程變得更容易:) –

+0

pleasd添加'EXPLAIN ' – VMai

+0

你應該問http://dba.stackexchange.com/ –

回答

0

我想你想的第一張照片(最低ID),和圖片是必需的,那裏的一切是可選的。

我想你正在做子查詢,因爲你認爲連接不相關的子查詢(只連接一次連接的表)會比關聯的子查詢或簡單的JOIN快。但是,最終不得不查找記錄兩次,而第二次查找(針對實際連接)不能使用索引,因爲派生(臨時表)沒有索引。

嘗試正常連接:

SELECT items.*, 
    p.file AS item_pic, 
    COALESCE(i_f.id, 0) AS favorite_id, 
    COUNT(f.item_id) AS favorite_count, 
    COUNT(b.item_id) AS num_buys, 
    COUNT(c.item_id) AS comment_count 
FROM items i 
STRAIGHT_JOIN item_pics p 
    ON p.item_id = i.id 
LEFT JOIN item_pics p2 
    ON p2.item_id = i.id 
    AND p2.id < p1.id 
LEFT JOIN item_favorites f 
    ON f.item_id = i.id 
LEFT JOIN purchases b 
    ON b.item_id = i.id 
LEFT JOIN comments c 
    ON c.item_id = i.id 
LEFT JOIN item_favorites AS i_f 
    ON i_f.item_id = i.id 
    AND i_f.userid = '14' 
WHERE p2.id IS NULL 
GROUP BY i.id 
LIMIT 20 

圖像時,雙連接是一種反連接WHERE p2.id IS NULL,檢索與最低id圖片。

+0

這不能正常工作。我必須最終取消查詢並重新啓動MySQL,因爲它消耗很多資源。這是EXPLAIN的結果http://www.hostingbytes.us/images/4/3511352.png – Shawn

+0

是否有更多的項目比圖片?我將INNER JOIN更改爲STRAIGHT_JOIN,強制它掃描項目而不是圖片。另外,也許你在註釋上輸入了連接錯誤,因爲它不應該看起來像這樣。它應該使用評論的索引。 –

+0

還有更多的項目,然後幾千圖片。我確實在評論中發現了一個問題,索引的類型錯誤。 INNER JOIN仍然會導致它掛起,但STRAIGHT_JOIN會將其降至2.5-3秒。這是我想改善的地方。新的EXPLAIN http://www.hostingbytes.us/images/4/4333434.png – Shawn

相關問題