Php order by rand()在大型邮件中遇到麻烦
我有这段代码,这段代码遇到了麻烦,需要执行很多时间来显示来自DB的随机帖子:Php order by rand()在大型邮件中遇到麻烦,php,mysql,random,sql-order-by,Php,Mysql,Random,Sql Order By,我有这段代码,这段代码遇到了麻烦,需要执行很多时间来显示来自DB的随机帖子: $totalrows = 10; $sql = "SELECT posts.Tags as tags, posts.OwnerUserId as postsid, posts.Id as postid, posts.Body as body, posts.Title as title, users.Id as userid, users.DisplayName as usersname
$totalrows = 10;
$sql = "SELECT
posts.Tags as tags,
posts.OwnerUserId as postsid,
posts.Id as postid,
posts.Body as body,
posts.Title as title,
users.Id as userid,
users.DisplayName as usersname
FROM posts
JOIN users ON posts.OwnerUserId = users.Id
WHERE posts.Title != '' order by rand() asc limit " . $totalrows;
$r = mysql_query($sql) or die(mysql_error());
请告诉我我应该改变什么来更快速地显示随机帖子
你好,丹兰特很贵。这会有帮助:我现在还没有测试的方法,但它应该会提供相当均匀的分布,我怀疑速度会是一个问题。在PHP中选择一些随机数,并执行一些简单的模数运算,这些运算应该足够随机,以便对行进行排序 如果我选择的确切数字没有给出好的结果,你可能会选择一些好的结果
$totalrows = 10;
$m = rand(31,61);
$k = randint(10,20);
$offset = rand(200,500) % $m;
$sql = ... "ORDER BY (post_id + $offset + $k*(post_id MOD 8)) MOD $m LIMIT $totalRows";
$r = mysql_query($sql) or die(mysql_error());
如果这仍然太慢,您可以尝试将一些基本的随机性作为“粗略”过滤器放入WHERE子句中,这样就不必对太多行进行排序。但是,请记住,它应该比您按顺序执行的任何操作都要简单,否则您将再次执行相同的慢速操作
让我知道这对你是否有效,我很好奇,希望我能自己用SQL测试一下。我在Python中尝试了一些类似的方法,将id设置为1-20000,发行版看起来很不错,但这并没有告诉我SQL中的执行速度,代码的问题是 你需要得到10个随机帖子 您需要获取发布消息的人的姓名 它们应该是随机的,但是连接会花费时间。 我建议你把它们分开 $sql=选择posts.id,其中posts.title!=按兰特asc限额订购$总计行数 执行结果,然后以csv格式内爆结果 $csvResult=2,3,4,5这些数字是随机帖子的ID。 在你的第二个问题中 $sql=select posts.*,users.*从posts中加入posts.owneruserid=user.id中的用户,其中posts.id位于$csvResult $r=mysql\u查询$sql或diemysql\u错误 希望这能缩短时间
$sql = "select posts.id from posts where posts.title != '' order by rand() asc limit " . $totalrows;
$result = mysql_query($sql) or die(mysql_error());
$tmpArray = array();
while($row = mysql_fetch_array($result)){
$tmpArray[] = $row['id']; // This will add all items to array
}
$csvResult = implode(',',$tmpArray);
$sql = " select posts.*, users.* From posts join users on posts.owneruserid = user.id where posts.id in (" . $csvResult . ")";
$r = mysql_query($sql) or die(mysql_error());
请检查是否有任何打字错误和列名。还有一种方法
$totalrows = 10;
$sql = "SELECT
posts.Tags as tags,
posts.OwnerUserId as postsid,
posts.Id as postid,
posts.Body as body,
posts.Title as title,
users.Id as userid,
users.DisplayName as usersname
FROM posts
JOIN users ON posts.OwnerUserId = users.Id
JOIN (select posts.id from posts where posts.title != '' order by rand() asc limit " . $totalrows .") AS tmp_result
ON (posts.Id = tmp_result.Id)";
$r = mysql_query($sql) or die(mysql_error());
嗯,我不知道这是否会加快您的脚本速度:D现在完全取决于您的记录。ORDER BY RAND的性能已经显示出固有的不好,请查看如何更改我的php代码,尽管注意这种方法的注意事项。在计划的压缩id序列值或间接表上的二级索引可以处理许多缺少序列id的问题,或者即使不能假定序列id也可以工作。您好Jon,我遇到了致命错误:调用未定义函数randinto抱歉,只是rand not randint。另外,我发现其中一些值应该是硬编码的,而不是随机的,我会按照你的建议进行更改,我得到了这个错误:你的SQL语法有一个错误;查看与您的MySQL服务器版本对应的手册,了解在“where posts.Title!”附近使用的正确语法在第1行按兰德asc限制10'订购您正在使用的MySQL版本。我刚刚测试了我的db select section_id,它来自mc_sections,其中section_nick!=order by rand asc limit 2成功了EDI发布了$sql=select posts.id where posts.title!=按兰特asc限额订购$总计行数;但它没有任何发件人,请更正$sql=从posts where posts.title!=中选择posts.id按兰特asc限额订购$总计行数;另外,在本例中,请在第一次查询中获取的列上添加索引。ID和标题要求15声誉和我没有这个代表请拆分查询,在我上次的回答中我告诉过你,但是当你发回查询时,它没有拆分。在第一个查询中,我们得到10个随机id,在第二个查询中,我们只得到这10个随机结果的其他详细信息。$sql=select posts.*,users.*From posts在posts.owneruserid=user.id中加入用户,posts.id在其中$csvResult;上次失踪,你好,阿米尔,谢谢更新。脚本现在显示页面,但是对于标题只显示没有标题的标题名称Hello Amir,这个解决方案非常好。非常感谢,先生!亲爱的Aamri,我使用了上面的脚本,但在MySql中遇到了问题,我认为这会造成太多的持久连接,并冻结服务器,需要重新启动。我应该添加什么来限制它或添加连接超时?我应该包括什么解决方案?我试图在一个查询中完成它。。。请参考我的另一个答案,将这个问题一分为二。。你不能只是复制我发布的代码,所以要修改它并删除任何打字错误。