MYSQL:使用rand()排序查询非常缓慢

7

我需要从一张表中随机选择30条记录,但是查询时间不能超过1秒,否则当多个用户访问时会拖慢mysql的速度。

这是查询语句:

SELECT relationship, COUNT(id) AS number FROM FR_user_friends GROUP BY relationship ORDER BY rand() LIMIT 30

您知道如何加快此查询速度吗?谢谢。

如果我去掉 rand(),查询速度就很快。我们必须找到替代 rand() 的方法。


3
可能是如何优化MySQL的ORDER BY RAND()函数?的重复问题。 - A.L
我认为您需要在“relationship”列上创建索引。 - devpro
它已经被索引了。 - Mario Chiuri
只是好奇,你可以在连接的数据的子查询结果上运行rand()来加快速度吗? - ale8oneboy
3个回答

9

ORDER BY RAND()会使引擎为所有行生成随机值,因此如果您想从大表中选择几行,则性能非常差。

例如,您可以在php中生成30个在范围[1,最大行号]内的随机值,并选择第一个行号大于或等于随机值的行,带上 LIMIT 1.

SQL-only的解决方法可以在How can i optimize MySQL's ORDER BY RAND() function?找到(但一些也不是那么简单)。


7
可以的。;-P 但是,SO不是一个编程服务网站,而是用于帮助解决特定问题的平台。因此,我建议您首先自己尝试一下。 - syck

3

这个查询应该比你的查询快得多

SELECT relationship, id 
FROM FR_user_friends fr1 
JOIN (
  SELECT CEIL(RAND() * ( SELECT MAX(id) FROM FR_user_friends )) AS id ) AS fr2 
  ON fr1.id >= fr2.id 
  LIMIT 0,30

我还建议在这里阅读更多:哪个更快?


3

RAND()函数速度太慢,消耗CPU过多。它为每一行生成一个随机数并选择最小的那个,所以速度很慢。

为了加快速度,您可以在PHP中生成一个随机数,并在LIMIT子句中使用,如下所示:

$firstClauseLimit = rand(0,20); // create an int random number between 0 to 20

"... ... LIMIT $firstClauseLimit,1"

通过这种方式,它将更快。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接