我有这段代码,这段代码遇到麻烦,需要花很多时间来显示来自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());
请告诉我应该更改哪些更快速地显示随机帖子?
的问候,丹
答案 0 :(得分:2)
rand()非常昂贵。这将有助于:http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/
答案 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)
您的代码存在问题。
我建议你拆分它们,
$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完全取决于你的记录。