按rand()排序会给大型帖子带来麻烦

时间:2011-01-10 07:35:05

标签: php mysql random sql-order-by

我有这段代码,这段代码遇到麻烦,需要花很多时间来显示来自DB的RANDOM帖子:

$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());

请告诉我应该更改哪些更快速地显示随机帖子?

的问候,丹

5 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

 $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());

请检查是否存在拼写错误和列名。

答案 2 :(得分:0)

我现在没有测试方法,但是应该给出相当均匀的分布,我怀疑速度是个问题。在PHP中选择一些随机数ONCE并执行一些简单的模数运算,这些运算应该是“足够随机”来排序你的行。

如果我选择的确切数字没有给出好的结果,你可以选择一些。

$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子句中,因此不必排序那么多行。但是,请记住,它应该比您在ORDER BY中所做的更简单,或者您只是再次执行相同的慢速操作。

让我知道这是否适合您,我很好奇,并希望我可以在SQL中自己测试它。我在Python中尝试使用类似于id为1-20000的类似的东西,发布看起来相当不错,但这并没有告诉我任何关于SQL执行速度的信息

答案 3 :(得分:0)

您的代码存在问题。

  1. 你需要获得10个randome帖子
  2. 您需要获取发布者的姓名
  3. 它们应该是随机的,但是连接会让它花时间。
  4. 我建议你拆分它们,

    $sql = "select posts.id where posts.title != '' order by rand() asc limit " . $totalrows;

    执行结果,然后将结果内嵌到csv formate中 $csvResult = 2,3,4,5这些数字是随机帖子的ID。 在您的第二个查询中

    $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());

    希望这会减少时间。

答案 4 :(得分:0)

另一种方式

$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完全取决于你的记录。