According to this link, ORDER BY RAND() is innefiencient as hell
考虑到这一点,如果我的Id
(主键)不是连续的,我如何优化随机行查询到mysql(AKA,我不能只做rand(1, max())
?
答案 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_seek
和mysql_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;