加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – 从mysql数据库返回随机行而不使用rand()

发布时间:2020-12-13 21:38:00 所属栏目:PHP教程 来源:网络整理
导读:我希望能够从数据库中提取15个左右的记录.我已经看到使用WHERE id = rand()可能会导致性能问题,因为我的数据库变大了.我见过的所有解决方案都是为了选择单个随机记录.我想得到倍数. 有谁知道为大型数据库执行此操作的有效方法? 编辑: 进一步编辑和测试:
我希望能够从数据库中提取15个左右的记录.我已经看到使用WHERE id = rand()可能会导致性能问题,因为我的数据库变大了.我见过的所有解决方案都是为了选择单个随机记录.我想得到倍数.

有谁知道为大型数据库执行此操作的有效方法?

编辑:

进一步编辑和测试:

我在使用MyISAM的新数据库上创建了一个相当简单的表.我给了这三个字段:autokey(无符号自动数字键)bigdata(一个大blob)和更多(一个中等int).然后我将随机数据应用到表中并使用Navicat运行一系列查询.结果如下:

查询1:按照rand()限制15从测试顺序中选择*

Query 2: select * 
          from 
      test 
          join 
      (select round(rand()*(select max(autokey) from test)) as val from test limit 15)                                           as rnd
      on 
          rnd.val=test.autokey;`

(我尝试了选择和选择不同,它没有明显的区别)

和:

Query 3 (I only ran this on the second test):
SELECT  *
    FROM    (
    SELECT  @cnt := COUNT(*) + 1,@lim := 10
    FROM    test
    ) vars
    STRAIGHT_JOIN
    (
    SELECT  r.*,@lim := @lim - 1
    FROM    test r
    WHERE   (@cnt := @cnt - 1)
            AND RAND(20090301) < @lim / @cnt
    ) i
ROWS:            QUERY 1:               QUERY 2:         QUERY 3:
2,060,922          2.977s                 0.002s            N/A

3,043,406          5.334s                 0.001s            1.260     

我想做更多的行,所以我可以看到查询3如何缩放,但此刻,似乎明显的赢家是查询2.

在我完成此测试并声明答案之前,当我设置了所有这些数据和测试环境时,是否有人可以推荐任何进一步的测试?

解决方法

尝试:

select * from table order by rand() limit 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中没有generate_series这样的东西.我的错.我们实际上不需要它:

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;

附:如果我不希望返回重复项,我可以在随机生成器表达式中使用(选择distinct […]).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读