mysql命令由rand()性能问题和解决方案

时间:2013-01-15 03:40:26

标签: php mysql

我正在使用rand()的命令从数据库生成随机行而没有任何问题,但我认为随着数据库大小的增加,这个rand()导致服务器上的负载很重,所以我正在寻找替代方案,我试着通过生成一个随机数使用php rand()函数并将其作为id在mysql查询中,它非常非常快,因为mysql知道行id 但问题是在我的表中所有数字都不是availbale.for例如1,2,5,9,12之类的。

如果php rand()生成数字3,4等,则查询将为空,因为没有数字3,4等的id。

从php生成随机数的最佳方法是什么,但它应该在该表中生成可用的no,所以它必须检查table.please advise。

$id23=rand(1,100000000);
    SELECT items FROM tablea where status='0' and id='$id23' LIMIT 1

上述查询速度很快,但有时会生成数据库中不可用的查询。

    SELECT items FROM tablea where status=0 order by rand() LIMIT 1

上述查询太慢,导致服务器负载过重

4 个答案:

答案 0 :(得分:9)

使用您的数据库从表中查找最大值,生成小于或等于该值的随机数,抓住id大于或等于随机数的第一行。没有必要的PHP。

SELECT items
FROM tablea
WHERE status = '0' and
      id >= FLOOR(1 + RAND() * (SELECT MAX(id) FROM tablea))
LIMIT 1

答案 1 :(得分:7)

首先,所有都生成从1到MAX(id)的随机值,而不是100000000。

然后至少有几个好的解决方案:

  1. 使用>而不是=

    SELECT items FROM tablea where status='0' and id>'$id23' LIMIT 1
    

    (status,id,items)上创建一个索引,使其成为仅索引查询。

  2. 使用=,但如果找不到匹配则只需使用其他随机值重试。有时需要多次尝试,但通常只需要一次尝试。 =应该更快,因为它可以使用主键。如果它更快并且在90%的时间内一次尝试,那么当它需要多次尝试时,这可以弥补其他10%的时间。取决于您的id值中有多少差距。

答案 2 :(得分:1)

你是对的,如果你正在处理大型数据集,ORDER BY RAND()不是一个好的解决方案。根据需要随机化的频率,您可以做的是生成一个带有随机数的列,然后以某个预定义的间隔更新该数字。

您将获取该列并将其用作排序索引。这适用于繁重的读取环境,并在一段时间内产生可预测的随机顺序。

答案 3 :(得分:1)

可能的解决方案是使用限制:

$id23=rand(1,$numberOfRows);

SELECT items FROM tablea where status='0' LIMIT $id23 1

这不会产生任何遗漏的行(但提到hek2mgl)需要知道select中的行数。