随机记录Mysql PHP

随机记录Mysql PHP,php,mysql,Php,Mysql,我已经读到,在大型数据库上使用ORDER BY RAND()运行SQL查询不是一个好主意 这是我破解密码的方法。代码需要从数据库中选择10个随机ID,然后进行第二次选择以获取随机行 $sql = "SELECT id FROM table WHERE image != '' ORDER BY id DESC LIMIT 50;"; $result = mysql_query($sql); while($row = mysql_fetch_array($result)) {

我已经读到,在大型数据库上使用ORDER BY RAND()运行SQL查询不是一个好主意

这是我破解密码的方法。代码需要从数据库中选择10个随机ID,然后进行第二次选择以获取随机行

$sql = "SELECT id FROM table WHERE image != ''
        ORDER BY id DESC LIMIT 50;";

$result = mysql_query($sql);


while($row = mysql_fetch_array($result))
{
    foreach($row as $key => $value)
    {
        $array[] = $value;
    }
}
$rand_keys = array_rand($array, 10);

foreach($rand_keys as $value)
{

    $rand_arr[] = $array[$value];

}
$rand_list = implode("," , $rand_arr);

$sql = "SELECT image FROM table
        WHERE image != ''
        AND id IN ($rand_list)";
$result = mysql_query($sql);
有没有加快或简化的建议?

五件四件事:

  • 如果您只需要12个id,为什么要获取50个id?(您从最后50个ID中选择了12个ID——这是有道理的,尽管在一般意义上不是特别随机的——这是有意从您的行子集中选择随机行的吗?)

  • 您是否分析过SQL语句
    orderbyrand()
    ,看看它对您来说是否慢?您的数据集有多大

  • 你不需要
    WHERE图像!=''
    在上一次查询中,因为您只选择了
    id
    s,而
    image!=''

  • 你为什么要做
    array\u rand($array,10)
    -你说你想要12个值

  • 您可以简化随机值的选取,如下所示:

  • SELECT MIN(id) as min, MAX(id) as max FROM table
    

    $rand\u arr=array\u rand(array\u flip($array),12)

    我同意上面的第1点和第2点-如果您可以在数据所在的同一级别在应用程序中执行随机数据的选择,那么您需要编写的代码就越少。

    没有特别好的方法可以优雅地完成这项工作

    但是你可以从多个方向来破解它。如果您的数据集大小合适(对于“order by rand()”来说太大,但不是太大),具有连续的id值,并且通常不会删除太多,那么您可以始终执行以下操作:

    SELECT MIN(id) as min, MAX(id) as max FROM table
    
    在“min”和“max”(包括)之间生成若干个N的随机整数。我们称之为50吧。如果从不从表中删除任何内容,N可能是12。如果你删除了,做一些餐巾纸算术,算出一个好的数字。你可能会在高位上犯错

    SELECT * FROM table WHERE id IN (<your set of integers>) AND image_id = '' LIMIT 12;
    
    从表中选择*,其中id IN()和image_id=''LIMIT 12;
    
    检查以确保至少有12个结果。如果没有,基本上重复并合并


    对于大型集合,此方法应该比ORDER BY RAND()更有效,尤其是在ID序列不是非常稀疏的情况下。

    我将重点介绍Dominic的第5点,这是一种随机检索数据的影响较小的方法。 您还可以
    sort()
    该ID列表(我相信MySQL会检测到这一点,并跳过对该列表的排序)


    对于涉及物化视图(本质上是缓存表)的大型数据集和高请求率,还有其他一些技术。您正在试图解决一个大而繁忙的表上存在的性能问题吗?

    另一种选择是使用随机种子哈希函数并对其进行排序

    检索表的最大和最小ID,并使用PHP的rand()函数在最大和最小值之间生成一个随机数

    然后使用该数字为散列函数设定种子。假设SQL中的{salt}表示PHP生成的随机整数

    SELECT image FROM table
    WHERE image != ''
    ORDER BY MOD(ABS({salt}-id), MOD({salt}, 10)), ABS({salt}-id));
    

    在PHP中执行MOD({salt},10)计算并在查询中传递值时,可以对其进行一些优化。

    如果行大小不是太大,我只需选择50行并在应用程序中保留12行的随机列表即可。是的,这意味着您将丢弃80%的选定行。当你说50分之80时,这真的是犯罪吗?这是SQL不擅长的事情。

    我喜欢这种方法,但它只适用于自动增量单调的单一主设置:自动增量、自动增量偏移设置可以分散这些ID。这一点很好。这只在你开始处理多个主机之前有效。我真的会避免把
    orderbyrand()
    作为一个普遍的习惯。我见过这张只有几十万行的密萨姆桌子。来吧,多米尼克#3和#4是明显的打字错误/被忽略的想法。我的错误#5是非常有帮助的#我心里想的是2。我在一个共享服务器上运行这段代码,它使我的网站停止运行(实际上与ORDER BY rand()的效果相同)。这让我完全重新考虑随机行,即提供随机图像。