我读过在大型数据库上使用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);
有关加快或简化的建议吗?
答案 0 :(得分:2)
五四件事:
如果你只需要12个,你为什么要提取50 (你从过去的50个中挑选了12个 - 这是有意义的,但不是特别的一般意义上的随机意义 - 是故意想要从中选择随机行的行的子集吗?)。id
?
您是否已对SQL语句ORDER BY RAND()
进行了分析,以确定它是否对您来说很慢?您的数据集有多大?
您在上次查询中不需要WHERE image != ''
,因为您已经选择了id
的{{1}}。
你为什么要做image != ''
- 你说你想要12个值?
您可以简化这样的随机值的选择:
array_rand($array, 10)
答案 1 :(得分:0)
我同意上面的第1点和第2点 - 如果您可以在数据所在的同一级别中对应用程序中的随机数据进行选择,那么您需要编写相同的东西
答案 2 :(得分:0)
没有特别好的方法可以做到这一点。
但你可以从多个方向来解决它。如果您的数据集大小合适(对于“按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序列不是很稀疏。
答案 3 :(得分:0)
我将关注Dominic的第5点作为一种相对较低的影响方式来随机检索数据。
你也可以sort()
那个ID列表(我相信MySQL会检测到这个并跳过为你排序的那个列表。)
大数据集和高请求率的其他技术涉及物化视图(基本上是缓存表)。是否正试图在繁忙的大桌上解决现有的性能问题?
答案 4 :(得分:0)
另一种选择是使用随机种子散列函数并对其进行排序。
检索表的最大和最小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)计算并在查询中传递值的位。
答案 5 :(得分:0)
如果行大小不是太大,我会简单地选择50行并在应用程序中保留其中12行的随机列表。是的,这意味着您丢弃了80%的选定行。当你说话时,80%的80%真的是犯罪吗?这是SQL不擅长的东西。