随机记录 Mysql PHP

Posted

技术标签:

【中文标题】随机记录 Mysql PHP【英文标题】:Random Records Mysql PHP 【发布时间】:2009-11-05 06:28:30 【问题描述】:

我了解到在大型数据库上使用 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);

有什么加快或简化的建议吗?

【问题讨论】:

【参考方案1】:

四件事:

    如果您只需要 12 个,为什么要获取 50 个 ids?(您从最后 50 个 id 中挑选 12 个 - 这是有道理的,尽管在这个词的一般意义 - 是故意要从中选择随机行的行的子集吗?)。

    您是否分析了 SQL 语句 ORDER BY RAND() 以查看它是否对您来说很慢?你的数据集有多大?

    您不需要在最后一个查询中使用WHERE image != '',因为您已经只选择了ids,其中image != ''

    你为什么要 array_rand($array, 10) - 你说你想要 12 个值?

    您可以像这样简化随机值的挑选:

$rand_arr = array_rand(array_flip($array), 12);

【讨论】:

我真的会避免将order by rand() 作为一般习惯。我见过这个只有几十万行的繁忙的 MyISAM 表。 现在来吧,多米尼克。 #3 和 #4 是明显的拼写错误/被忽视的想法。我的错。 #5 非常有帮助。 #2在我的脑海中。我在共享服务器上运行此代码,它使我的网站停止运行(实际上与 ORDER BY rand() 的效果相同。)这让我完全重新考虑随机行,即。提供随机图片。【参考方案2】:

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

【讨论】:

【参考方案3】:

没有特别好的方法可以优雅地做到这一点。

但是您可以从多个方向破解它。如果您的数据集大小合适(对于“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;

检查以确保您至少获得了 12 个结果。如果没有,基本上重复并结合。

对于大型集合,此方法应该比 ORDER BY RAND() 工作得更好,尤其是在您的 ID 序列不是很稀疏的情况下。

【讨论】:

我喜欢这种方法,但它只适用于 auto_increment 是单调的单主设置:auto_increment_increment、auto_increment_offset 设置可以分散这些 id。 好点。这仅在您开始处理多个主人之前有效。【参考方案4】:

我将重点关注 Dominic 的第 5 点,作为随机检索数据的影响相当低的方式。 您也可以sort() 该 ID 列表(我相信 MySQL 会检测到这一点并为您跳过对该列表的排序。)

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

【讨论】:

【参考方案5】:

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

检索表格的最大和最小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) 计算并在查询中传递值。

【讨论】:

【参考方案6】:

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

【讨论】:

以上是关于随机记录 Mysql PHP的主要内容,如果未能解决你的问题,请参考以下文章

从mysql数据库中提取5条随机记录[关闭]

mysql随机查询符合条件的几条记录

mysql随机查询记录的高效率方法

MYSQL 从每个类别中选择一个随机记录

使用 CodeIgniter 从 mysql 数据库中随机记录

MySQL使用rand 随机查询记录效率测试