MySQL ORDER BY RAND()和WHERE子句有什么更好的?

时间:2015-09-09 06:31:46

标签: mysql performance

我理解ORDER BY RAND()很慢(使用它来获取随机的数据子集)。但我想知道是否有WHERE子句或像JOIN这样的过滤函数,它会改进吗?随着时间的推移,我的数据库大小会增长。但是,如果我希望WHERE将记录数量限制为1000,那么ORDER BY RAND()仅适用于1000条记录是否正确?

如果您需要更多详细信息

我正在做的事实上是为幸运抽奖赢得胜利者。所以我想随机选择一些获奖者。简单的例子是:

SELECT * FROM luckydrawchance
WHERE luckydraw = 1
ORDER BY RAND()
LIMIT 5

但有些用户可能有更多的获胜机会,所以我在想

SELECT * FROM luckydrawchance
WHERE luckydraw = 1
ORDER BY RAND() * (-chances)
LIMIT 5

也许代替RAND() * (-chances)我需要别的东西(我读到这不会给出正确的概率分布)但只是为了给你一个想法。

2 个答案:

答案 0 :(得分:0)

EDIT2:从您的额外信息可以清楚地看出,公平的随机性非常重要,但您只需要几行,而且您不需要经常使用它们。所以我会结合两个步骤。 numrows非常大致是表中的行数,numwinners通缉获胜者的数量

  • 计算part = 5 * numwinners / numrows
  • 的方式查询您的数据
    select * from users where rand() < [part] order by rand() limit numwinners
    

如果它少于numwinners行(非常罕见,但可能发生),则重复查询。

编辑:更明确

如果您只需要数据的任意子集进行一次性分析,您应该了解样本数据与整个表格的比较。假设它有点小于0.1%和1000行,那么你可以尝试

where rand() < 0.001
LIMIT 1000 // EDIT of course you should use limit

这也会产生大量的rand()数字,但不必为那些rand()数字订购数据。您必须根据您的需要采用0.001,并且无法保证良好的解决方案。如果你的数字太小或者你只是运气不好(随机!),你得到的数据太少了。如果你把它做得太大,你总是只能选择较旧的(或者只是更新的)条目。

如果您经常需要随机样本,那么您可以使用随机数分配固定字段,但您必须仔细阅读样本。如果您将范围[ 0, 1 ]扩展到您的行并想要公平的样本,那么您可以在[ 0.1, 0.9 ]之间创建一个检查随机数,并读取[check - 0.1, check+0.1]内的所有数据。您可以偶尔重新调整分配的随机数(例如,在晚上)。

答案 1 :(得分:0)

几乎任何从1000行表中获取随机5行的尝试都会击中所有1000行。 flaschenpost将获得5到1000之间的某个位置;它会有所不同。

Here是我所知道的唯一真正有效的随机提取器。你还没有提供足够的关于你的桌子的详细信息,我可以为你挑选五个。