нет. Способ узнать количество записей я полагаю любой читатель ветки справится сам. Перевожу на русский: происходит выборка изо всей базы и из нее случайно выбираются несколько нужных. Не вижу оснований чтобы это хоть когда-то стало работать быстрее order by rand() хе-хе-хе, не стоит бросаться такими фразами :wink: я уже написал, что надо использовать order by id Варианты перебора БЕЗ использования индексов неизбежно будут дико тормозить на большой базе. Единственный способ сделать по уму - это суметь реализовать выборку с использованием индекса. Именно это я и пытаюсь сделать в своем примере - это возможно, надо только разобраться как именно заставить оптимизатор mysql его включить. ссылку по теме я подкинул, но до завтра точно до mysql5 не доберусь.
Есть сомнения? У Вас 10 выборок у меня одна. Я тоже не вижу. Но, как ни странно, работает чутка быстрее.
угу, работает быстрее, потому что выбирает не всю базу а только ид. Хотя конкретно твой код я не понял, сделал так: PHP: if ($variant==1) { $sql="SELECT COUNT( * ) as a FROM `".$newstbl."`"; $q=mysql_query($sql); $row=mysql_fetch_assoc($q); $newsnumrows=$row['a']; $ids=array(); for ($i=0;$i<$newsonpage;$i++) { $ids[]=rand(0,$newsnumrows); } $sql0=" SET @n = 0"; mysql_query($sql0); $sql="SELECT * FROM ".$newstbl." t1 , (SELECT @n:=@n+1 AS num, ".$id." FROM ".$newstbl.") t WHERE num IN (".implode(',',$ids).") AND t.".$id."=t1.".$id." "; $q=mysql_query($sql); while($row=mysql_fetch_assoc($q)) { $n[]=$row; } } Пока вариант лучший, но все равно долго и надо искать возможность работать по индексам.
Варианты для Dagdamor ))) http://akinas.com/pages/en/blog/mysql_random_row/ но по видимому самым быстрым вариантом будет создание поля sortid и пересчет его при удалении записи. Или во вспомогательной таблице хранить удаленные sortid для повторного использования. Если не будет дополнительных условий. ))) Черт.
armadillo, вот так мы плавно и пришли к моему варианту... :b или неразрывные id c откидыванием строк по is_deleted=1
нет, id записи должен быть уникальным, id удаленной записи не должен отдаваться новой. а sort_id годится только для полного отсутствия условий, where news_date> now() - interval 30 day уже не подходит.
armadillo Там только выбор одной записи. Одну случайную запись и так понятно, как выбрать речь о выборе случайной подборки из N элементов. Горбунов Олег Неужели не интересно придумать способ для решения задачи БЕЗ накладывания условий на таблицу и без создания дополнительных таблиц поддерживать в твоей дополнительной таблице порядок тоже ведь как-то надо...
dark-demon Кстати, это совсем даже не глупость... у варианта с пометкой записей на удаление есть одно преимущество перед обычным удалением записи - "удаленные" записи можно потом выбрать. Так что если удаленных строк относительно немного, алгоритм выборки N случайных значений можно изменить так: 1. Выбираем MAX(id). 2. Выбираем список всех удаленных id ("черный список"). 3. Модифицируем функцию генерации списка из N случайных id от 1 до MAX так, чтобы она не возвращала значения из "черного списка". 4. Делаем SELECT * FROM table WHERE id IN (список). Должно летать
Dagdamor? Где я предлагал делать дополнительную таблицу??? Я сказал, что удаленные записи откинутся простейшим условием во WHERE, а условие группировки положить в HAVING, который для этого и преднаазначен. Это не глупость - это основы реляционных СУБД. Операция по удалению записей в индексированных таблицах всегда была нежелательной. А как я заметил, что я в основном работаю с Ораклом - там она вообще крайне неэффективна, в свете его «классической» идеологии и архитектуры.
> Я сказал, что удаленные записи откинутся простейшим условием во WHERE вследствии чего id неудалённых записей перестанут идти по порядку. за что боролись - на то и напоролись. > условие группировки положить в HAVING > Это не глупость - это основы реляционных СУБД пошёл биться апстенку...
Dagdamor, и что будет при большом числе удалённых записей? например, допустим их 200'000 из 1'000'000
dark-demon Я для кого написал фразу "если удаленных строк относительно немного"? Ясен палец, что после публикации алгоритма можно посидеть, подумать, поднатужиться и придумать ситуацию, в которой использовать данный алгоритм будет нерационально идеальных алгоритмов не существует...
не заметил. по любому, число удалённых записей будет всё время расти и рано или поздно придётся переписывать такие вот легкомысленные запросы с нетривиальной логикой.
похоже по скорости. PHP: $sql="select * from ".$newstbl.", (select ".$id." from ".$newstbl." order by rand() limit 15) tt where ".$newstbl.".".$id."=tt.".$id; но в любом случае стоит кешировать и подставлять разным пользователям разные только для данного пользователя варианты.
Dagdamor реализуй логику. )) если вместо инсерта сначала пытаться делать update ... where deleted=1 limit 1 то может что-то побыстрее и выйдет. а откуда новый уникальный ид брать? отдельное поле - переходящий sort_id?
Вопрос в тему - зачем выбирать ВСЕ записи кроме 10 последних? Если записей хотя-бы 1000, по какая нафиг разница 990 их или 1000 на экране будет? /* Режим телепатии ON */ Одним запросом невозможно сделать так, что бы выбрать N - 10 записей, т.к. N необходимо знать, а подзапросы в LIMIT MySQL делать не умеет. Так что делаем так: [SQL] SELECT COUNT(id) FROM table; [/SQL] После чего делаем N = N - 10 и выполняем запрос [SQL] SELECT * FROM table ORDER BY date ASC LIMIT 0, N [/SQL] и не забываем индексы на поле, по которому делаем ORDER BY /* Режим телепатии OFF */