У меня есть этот код, этот код вызывает проблемы и так много времени, чтобы его можно было запустить, чтобы показать 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());
Скажите, пожалуйста, что я должен изменить, чтобы показать случайные сообщения более quikly?
С уважением, Дэн
rand () очень дорого. Это поможет: http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/
$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());
Проверьте наличие опечаток и имен столбцов.
У меня нет средств проверить это прямо сейчас, но он должен дать довольно равномерное распределение, и я сомневаюсь, что скорость будет проблемой. Выберите некоторые случайные числа ONCE в 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 как «грубый» фильтр, поэтому не так много заказов нужно упорядочить. Однако имейте в виду, что это должно быть проще, чем все, что вы делаете в ORDER BY, или вы снова будете выполнять те же медленные операции.
Дайте мне знать, если это сработает для вас, мне любопытно, и я хотел бы сам проверить его в SQL. Распределения выглядят неплохо с моей попыткой чего-то подобного в Python для набора 'id's 1-20000, но это ничего не говорит мне о скорости выполнения в SQL
Проблема с вашим кодом.
Я предлагаю вам разбить их,
$sql = "select posts.id where posts.title != '' order by rand() asc limit " . $totalrows;
выполнить результат, а затем взорвать результат в csv $csvResult = 2,3,4,5
эти числа являются идентификаторами случайных сообщений. В вашем втором запросе
$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 полностью зависит от ваших записей.