【问题标题】:Return random results ( order by rand() )返回随机结果(按 rand() 排序)
【发布时间】:2013-05-31 10:53:31
【问题描述】:

我记得在某处读到,使用 rand() 的顺序是不好的,我刚开始翻页,发现一篇文章证明了这一点。对于大型数据库,按 rand() 排序可能会非常慢,建议的解决方案是在 php 中生成一个随机数并根据它进行选择。问题是我需要验证其他字段才能返回我的记录。我也可能删除了一些旧记录,这也可能导致问题。任何人都可以提供一种体面的方法来从表中选择一些符合某些条件的随机记录(例如字段 paid 必须等于 1 )?

【问题讨论】:

  • 如果您使用 php,请使用 'shuffle' 功能。所以得到你的结果,然后在你的程序中随机播放它们。
  • 但是如果我返回了 100,000 个结果,我不想获取所有结果
  • @FabianBigler 将大量结果拉入 php 以仅获取少数结果可能比 order by rand() limit N 慢得多。
  • 而@php_nub_qq 是表MyISAM 或INNODB
  • @Kevin 目前是 MyISAM,但如果我没有其他选择,我可能会考虑转换

标签: mysql random


【解决方案1】:

RAND() 排序可能很慢的原因是您强制数据库在返回任何内容之前对整个表进行实际排序。仅将负载减少到单个表扫描会快得多(尽管仍然有些慢)。

这意味着您可以通过避免排序来获得一部分:

  SELECT *
    FROM my_table
   WHERE RAND() < 0.1
ORDER BY RAND()
   LIMIT 100

这将选择表中所有行的大约 1%,对它们进行排序并返回前 100 个。请注意,这里的主要问题(以及@cmd 的答案)是您不能确定查询返回任何内容。

上述方法应涉及全表扫描(以决定使用哪些行),然后对大约 1% 的行进行排序。如果行数很多,可以相应减少百分比。

【讨论】:

  • 我需要确保我会返回一些东西,并且我需要确保返回的记录是完全随机的。如果没有更好的选择,我会使用@cmd 的建议并运行更多查询。
  • 但是@cmd 的建议也有同样的弱点——你不能确定它会返回任何东西。
  • 为什么不呢?我看不出它怎么可能不会返回任何东西。
  • ...上面的答案使用RAND(),这比仅使用主键选择要随机得多(这显然严重偏向于高数字)。
  • 如果随机数高于所有pk_id。但无论如何,它非常非常倾向于高数字,所以你不会得到任何接近均匀分布的东西。
【解决方案2】:

你需要它们有多随机?如果你不需要超级均匀的分布试试这个

select min(pk_id) from my_table where pk_id > %(random_number)s and paid=1 

其中%(random_number)s 是一个绑定变量,其中包含每次运行查询时重新生成的从0max(pk_id)-1 的随机数

【讨论】:

  • 这是个好主意,但我不能冒多次显示同一组结果的风险。那只会告诉人们我的随机化系统不好。 +rep 虽然
  • @php_nub_qq 如果每次执行查询都生成一个新的随机数,每次都是不同的记录
  • 是的,我知道,但我需要返回 2 到 8 条记录,我将其称为一组,如果随机数为 max(pk_id)-8(我将其设置为 max rand number ) 然后 pk_id-7 和 pk_id-6 将始终显示。如果 8 是我需要返回的记录数,最后 8 将始终是连续的。我不想运行 8 个单独的查询
  • @php_nub_qq 这是随机获取一条记录,如果表很大(仅按 rand 的时间顺序是一个问题),那么您可以多次调用它来获取您的设置
  • 我认为所写的查询根本不起作用。 SELECT MAX(ID) WHERE ID > 将始终返回相同的 MaxID? (表中存在的最大的一个)我认为您想通过 PK where ID > @some Random数字——注意不要投反对票,但我认为你犯了一个逻辑错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-23
  • 2015-01-14
相关资源
最近更新 更多