2012-02-23 22 views
3

我想優化這個查詢,因爲它運行的數據庫是巨大的,主機說這個查詢導致服務器上的嚴重負載。我已經閱讀了關於如何替換ORDER BY RAND()的其他一些答案,但我並不知道SQL來適應這些特定查詢的答案。誰能幫忙? TIA我如何優化這個SQL查詢與ORDER BY蘭德()

SELECT COUNT(p.prod_id) AS no_prod, s.* 
    FROM product p, seller s 
    WHERE s.admin_status = '1' 
    AND s.pay_status = '1' 
    AND s.sub_type != '' 
    AND p.seller_id = s.seller_id 
GROUP BY s.seller_id 
    HAVING COUNT(p.prod_id)>5 
ORDER BY RAND() 
    LIMIT 0, 4 
+0

什麼其他問題/答案你讀過?請鏈接? – PenguinCoder 2012-02-23 21:50:12

+1

我不明白這個查詢會如何工作 - 是不是抱怨SELECT中的字段是從GROUP BY中丟失的? – egrunin 2012-02-23 22:12:32

+0

@大部分涉及1個隨機行(LIMIT 1),比檢索4行更容易。第三個涉及多行,但沒有得到確切的答案。 – joshuahedlund 2012-02-23 22:17:52

回答

0

你可能會更好添加非唯一索引,其中包括領域seller.admin_status,seller.pay_status,seller.sub_type。通過索引WHERE子句中引用的字段,您將獲得最大的回報。

+1

我相信問題是ORDER BY RAND()不使用索引,而必須掃描整個表。 (http://ask.use-the-index-luke.com/questions/11/order-by-rand-can-use-index) – joshuahedlund 2012-02-23 22:24:51

0

基於http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/

SET @MAX_SELLER_ID = SELECT MAX(seller_id) FROM seller; 


SELECT COUNT(p.prod_id) AS no_prod, 
     s.* 

FROM (
    -- preselect a big bunch of random sellers 
    SELECT DISTINCT * 
    FROM seller 
    WHERE seller.id IN (
    FLOOR(RAND() * @MAX_SELLER_ID) 
    ,FLOOR(RAND() * @MAX_SELLER_ID) 
    ,... -- repeat or generate list of random ids in your app 
) 
) AS s 
INNER JOIN product p 

WHERE s.admin_status = '1' 
    AND s.pay_status = '1' 
    AND s.sub_type != '' 
    AND p.seller_id = s.seller_id 

GROUP BY s.seller_id 
HAVING COUNT(p.prod_id)>5 

ORDER BY RAND() 
LIMIT 0, 4; 
+0

謝謝,這工作!感謝您的幫助 – 2012-02-24 15:59:21

+0

很高興幫助。只是不要忘記檢查是否所有5個必需的行已被選中。 – biziclop 2012-02-24 16:08:25

0

嚴重的負荷是由您因ORDER BY RAND() SQL引起的。您可以谷歌,爲什麼這是一個問題,並建議修正如何以其他方式完成相同的效果。

我能找到後,一些谷歌上搜索從bug report關於Solaris系統上同樣的問題來了最好的解釋:

ORDER BY RAND()使用文件排序,不能以最快的速度表現爲ORDER BY some_key。 發生這種情況,因爲當您使用ORDER BY RAND()時,如果您編寫如下查詢,則會發生相同的問題: SELECT id, rand() FROM t1 ORDER BY RAND();這意味着將爲表中的每一行創建rand()。