当主键数据不连续时选择随机行

时间:2012-09-03 20:09:54

标签: php mysql

According to this link, ORDER BY RAND() is innefiencient as hell

考虑到这一点,如果我的Id(主键)不是连续的,我如何优化随机行查询到mysql(AKA,我不能只做rand(1, max())

5 个答案:

答案 0 :(得分:4)

让表随机排序的最好方法是添加一个额外的字段并用任意md5哈希填充它,并在该字段上创建索引。

这些哈希可以是你喜欢的任何哈希,只要它们都不同。我建议散列主键ID字段,加上任意盐字符串。

UPDATE myTable SET rand_hash = md5(concat(id,'anything here'))

有了这些,您将拥有一个非常完全随机的排序顺序。您可以通过创建另一个任意md5哈希来查询表,并查询最接近该值的记录。 MD5哈希值是随机分布的,因此每条记录都有相同的被选择机会。像这样的东西可以解决这个问题:

SELECT * FROM myTable WHERE rand_hash >= md5(now()) LIMIT 1

最好的一点是,这将是一个索引的查询,所以无论表中记录在哪里都会闪电般快速。

希望有所帮助。

答案 1 :(得分:0)

你可以ORDER BY id ASC,然后选择rand()行或下一个更高的行:

...
WHERE id >= rand(1, $max_id)
ORDER BY id ASC
LIMIT 1

答案 2 :(得分:0)

你可以随意使用mysql_fetch_array()

$query=sprintf("SELECT * FROM acb");
$check=mysql_query($query);
for($i=1,$i<=rand($min_id,$max_id,$i++)
$row=mysql_fetch_array($check, MYSQL_ASSOC);

现在$ row包含一个随机行 注意:这种方法对我来说似乎效率很低

答案 3 :(得分:0)

您可以在php中使用mysql_data_seek(resource $result, int $row_number)

$result = mysql_query( 'SELECT * FROM `table`' );
mysql_data_seek( $result , mt_rand( 0 , mysql_num_rows( $result ) ) );

mysql_data_seekmysql_num_rows不适用于无缓冲的查询。

答案 4 :(得分:0)

我尝试了以下查询。它比ORDER BY RAND()更快:

SELECT * FROM table WHERE (id >= RAND() * (SELECT MAX(id) FROM table) LIMIT 1;

如果列“id”是auto_increment,我测试此查询比以前快得多:

SELECT * FROM table WHERE (id >= RAND() * (SELECT id FROM table ORDER BY id DESC LIMIT 1)) LIMIT 1;