在MySQL中从大表中快速选择一个随机行。

11 浏览
0 Comments

在MySQL中从大表中快速选择一个随机行。

如何从一个大的MySQL表中快速选择一行随机数据?

我在使用PHP,但我对任何语言的解决方案都感兴趣。

0
0 Comments

问题的出现原因:

在使用MySQL数据库时,需要从一个大表中快速选择一个随机行。常规的做法是使用ORDER BY RAND()语句,但随着表的数据量增加,这种方法效率较低。

解决方法:

维基百科的MediaWiki使用了一种巧妙的方法来解决这个问题。他们在文章表中添加了一个额外的列,用于存储在文章创建时生成的随机数。要获取一个随机文章,只需要生成一个随机数,并获取随机数列中比该随机数稍大或稍小(具体是大还是小记不清了)的值对应的文章。配合索引,这种方法可以非常快速地获取到随机行。(需要注意的是,MediaWiki是使用PHP编写并开发于MySQL数据库上的)。

然而,这种方法可能会出现一个问题,即生成的随机数分布不均匀。据我记得,MediaWiki已经修复了这个问题,所以如果你决定使用这种方法,应该查看一下代码,了解当前的实现方式(可能是定期重新生成随机数列)。

另外,有人提醒说,对于获取N个随机结果的情况,这种方法可能不适用。因为可能会获取到较少的结果,或者结果的顺序可能与期望的不一致。

还有人提出了另一种思路,即在查询时仍然需要按随机数列进行排序。例如,如果随机数列是random_number,查询语句可能是这样的:"SELECT * FROM mytable WHERE random_number>$rand ORDER BY random_number LIMIT 1"。这种方法比使用ORDER BY RAND()是否更快速,还需要进一步测试和比较。

另外,还有人建议在随机数的最大值上设置一定的限制,以保证与表中当前记录数的相关性。例如,在记录数较少的情况下,如果有3个记录,假设随机数范围是0到100,并且随机数分别是49、50、51,那么最小值几乎不会被选中,因为最小值与中间值之间的差距非常小。因此,可能需要根据表的大小动态调整随机数的范围。

还有人对这种方法提出了疑问,认为这与仅仅在1到max(id)之间随机选择一个数字,然后选择对应ID的记录有什么区别。为什么需要额外的列呢?

以上就是关于从大表中快速选择随机行的问题出现原因和解决方法的整理。

0
0 Comments

问题的原因是希望在MySQL中从一个大表中快速选择一个随机行,但是使用常规的SELECT查询语句无法实现。文章提供了一种解决方法,通过使用嵌套查询和JOIN语句来实现。

解决方法如下:

1. 在外部代码的帮助下快速选择随机行。这种方法需要借助外部编程语言(如Python、PHP等)来实现。

2. 使用嵌套查询和JOIN语句。这种方法不需要外部代码的帮助,可以在单个查询中完成。

具体的解决方法如下所示:

SELECT name
  FROM random AS r1 JOIN
       (SELECT (RAND() *
                     (SELECT MAX(id)
                        FROM random)) AS id)
        AS r2
 WHERE r1.id >= r2.id
 ORDER BY r1.id ASC
 LIMIT 1;

需要注意的是,这种方法存在一个权衡:为了确保在第一次尝试时获得结果,任何在间隔之前的键都更有可能被选中。例如,给定两个键为1和10的记录,键为10的记录将有90%的概率被选中。

如果键是没有间隔的,并且避免使用WHERE和ORDER BY子句,可以获得更好的分布。可以查看文章中的更多细节和其他查询的优缺点。

然而,有时候当指定额外的参数(如WHERE r1.id >= r2.id AND r1.some_field=1)时,这个查询可能无法返回数据。对于如何解决这个问题,文章中并未给出明确的解决方法。

0
0 Comments

在处理大型MySQL表时,有时需要从表中快速选择一个随机行。根据上述内容,我们可以得出以下问题的原因和解决方法。

问题的原因是,如果我们使用ORDER BY RAND()来随机选择行,对于包含大量记录的表来说,这种方法效率非常低下,耗时较长。

解决方法如下:

1. 如果我们知道id是连续的且没有间隙,可以直接获取最大id,并计算一个随机id。

2. 如果id有间隙,但大部分值仍然是连续的,而且我们不关心略微倾斜的随机性,可以获取最大值,并计算一个id,然后选择第一个id等于或大于计算出的id的行。这种方法的缺点是,跟在间隙之后的id被选中的机会要比跟在其他id之后的机会更大。

3. 不要使用ORDER BY RAND()来随机选择行,也不要按GUID排序,因为它们都会导致表扫描的性能问题。

目前,对于包含100万条记录的表来说,使用ORDER BY RAND()的方法只需要几秒钟的时间,但效率仍然不高。

这些是快速从大型MySQL表中选择随机行的原因和解决方法。

0