使用group by和按rand排序的MySQL查询优化

时间:2012-06-08 07:32:02

标签: mysql optimization

我遇到以下查询的问题非常慢:

    SELECT A.* FROM B  
    INNER JOIN A ON A.id=B.fk_A  
    WHERE A.creationDate BETWEEN '20120309' AND '20120607'  
    GROUP BY A.id  
    ORDER BY RAND() 
    LIMIT 0,5

EXPLAIN:


    id  select_type table   type    possible_keys   key key_len ref rows    Extra
    1   SIMPLE  B   index   fk_A    fk_A    4   \N  58962   Using index; Using temporary; Using filesort
    1   SIMPLE  A   eq_ref  PRIMARY,creationDate    PRIMARY 4   B.fk_A  1   Using where

指数:


    A.id (int) = PRIMARY index
    A.creationDate (date) = index
    B.fk_A = index

你看到要优化的东西吗?

非常感谢您的建议

2 个答案:

答案 0 :(得分:1)

我认为RAND()函数会为每一行创建一个Rand()值(这就是using temporary显示的原因,而filesort因为它不能使用索引。

最好的方法是SELECT MAX(id) FROM a获取最大值。 然后在1和MAX之间创建5个随机数(id)并进行SELECT ... WHERE a.id IN (...)查询。

如果结果少于5行(因为已删除记录),请重复此过程直到您没事(或者最初创建100个随机数并将查询限制为5。

这不是100%的mysql解决方案,因为你必须在你的代码中执行逻辑,但我相信会更快。

<强>更新 刚刚在网上找到一篇有趣的文章,基本上讲的是:http://akinas.com/pages/en/blog/mysql_random_row/

答案 1 :(得分:1)

可能重写查询:

SELECT A.*
FROM A   
WHERE A.creationDate BETWEEN '20120309' AND '20120607'  
  AND EXISTS
      ( SELECT *
        FROM B
        WHERE A.id = B.fk_A
      )  
ORDER BY RAND() 
LIMIT 0,5