2012-02-23 51 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()。