Php 不使用rand()从mysql数据库返回随机行
我希望能够从数据库中提取15条左右的记录。我已经看到,随着数据库变得越来越大,使用WHERE id=rand可能会导致性能问题。我看到的所有解决方案都是针对选择单个随机记录。我想要倍数 有人知道一种有效的方法来处理大型数据库吗 编辑: 进一步编辑和测试: 我使用MyISAM在一个新数据库上创建了一个相当简单的表。我给了这3个字段:autokey unsigned auto number key bigdata一个大blob,还有一个中int。然后我将随机数据应用到表中,并使用Navicat运行一系列查询。结果如下: 查询1:按兰德限制从测试订单中选择*15 我尝试了select和select distinct两种方法,但没有明显的区别 以及: 我想做更多的行,这样我就可以看到Query3是如何伸缩的,但目前看来,显然胜利者是Query2 在我结束测试并声明答案之前,当我已经设置了所有这些数据和测试环境时,有人能推荐任何进一步的测试吗 更新:在中查看已接受的答案。它是纯mySQL,甚至处理均匀分布 id=rand或PHP中任何类似的问题在于,您无法确定该特定id是否仍然存在。因此,您需要使用LIMIT,这对于大量数据来说可能会变得很慢 作为替代方案,您可以尝试在PHP中使用循环 循环的作用是 使用rand创建一个随机整数,范围介于0和数据库中的记录数之间 查询数据库是否存在具有该ID的记录 如果存在,请将该数字添加到数组中 如果没有,请返回步骤1 当随机数数组包含所需数量的元素时,结束循环 这种方法可能会在一个碎片化的表中产生大量查询,但执行起来应该非常快。在某些情况下,它可能比极限兰德快Php 不使用rand()从mysql数据库返回随机行,php,mysql,random,Php,Mysql,Random,我希望能够从数据库中提取15条左右的记录。我已经看到,随着数据库变得越来越大,使用WHERE id=rand可能会导致性能问题。我看到的所有解决方案都是针对选择单个随机记录。我想要倍数 有人知道一种有效的方法来处理大型数据库吗 编辑: 进一步编辑和测试: 我使用MyISAM在一个新数据库上创建了一个相当简单的表。我给了这3个字段:autokey unsigned auto number key bigdata一个大blob,还有一个中int。然后我将随机数据应用到表中,并使用Navicat运行一
如@Luther所述,LIMIT方法无疑是最简单的代码方式。您可以使用所有结果进行查询,或者使用有限的结果进行查询,然后使用mysqli\u fetch\u all,后跟:
shuffle($a);
$a = array_slice($a, 0, 15);
尝试:
另一种可能更有效的方法是针对一组随机值进行连接。如果表中有一些连续的整数键,这应该可以工作。以下是我在postgres中的做法我的MySQL有点生锈了
select * from table join
(select (random()*maxid)::integer as val from generate_series(1,15)) as rnd
on rand.val=table.id;
其中,maxid是表中的最高id。若id有一个索引,那个么这意味着只有15个索引查找,所以它非常快
更新:
看起来MySQL中没有生成_系列这样的东西。是我的错。实际上,我们并不需要它:
select *
from
table
join
-- this just returns 15 random numbers.
-- I need `table` here only to produce rows for rand()
(select round(rand()*(select max(id) from table)) as val from table limit 15) as rnd
on
rnd.val=table.id;
另外,如果我不希望返回重复项,我可以在随机生成器表达式中使用select distinct[…]。用于大型数据集
select * from table order by rand() limit 15
这可能会耗费大量的时间和内存
如果您的数据记录碰巧被编号,您可以在编号栏上放置和索引,并执行以下操作:
select * from table where no >= rand() limit 15
或者最好在应用程序中生成随机数,然后
select * from table where no >= $rand and no <= $rand+15
如果您的数据不经常更改,那么可能值得添加这样的列编号,以提高选择的效率。假设MySQL支持嵌套查询,并且主键上的操作速度很快,我会尝试以下方法
select * from table where id in (select id from table order by rand() limit 15)
这些可能会有帮助:,这很难节省内存-他询问的是更大的数据量。他确实说过他只想要15行,这取决于查询带来的回退量,但实际上不是15行随机数据。它是一个随机行,然后是结果中的下14行,如果$rand恰好位于表中最后15条记录的范围内,它也将不起作用。
select * from table order by rand() limit 15
select * from table where no >= rand() limit 15
select * from table where no >= $rand and no <= $rand+15
select * from table where id in (select id from table order by rand() limit 15)