Спустя 9 минут, 12 секунд (18.03.2009 - 14:49) Viking написал(а):
select * from tablizza order by rand() limit 1;
Спустя 9 минут, 8 секунд (18.03.2009 - 14:58) nasferatu написал(а):
Viking, читал, что order и rand нежелательно вместе использовать. Или это не так????
Спустя 19 минут, 8 секунд (18.03.2009 - 15:18) Viking написал(а):
да, похоже оно сначала всю таблицу сортирует, а потом одну запись достает, т.е. работает медленно, должен быть нормальный способ, но сегодня я его не вижу
Спустя 7 минут, 8 секунд (18.03.2009 - 15:25) nasferatu написал(а):
может использовать два запроса??? сначала все записи, а потом брать айди из диапозона, но тогда есть вероятность ошибки, если какая-нибудь запись будет удалена
Спустя 6 минут, 41 секунда (18.03.2009 - 15:31) Viking написал(а):
видимо надо копать в сторону id=round(rand()*count(*)) но у меня сегодня как-то не копается...
Спустя 4 минуты, 2 секунды (18.03.2009 - 15:35) nasferatu написал(а):
поробуем в ту сторону покапать, может что-нибудь получится
Спустя 25 минут, 30 секунд (18.03.2009 - 16:01) sergeiss написал(а):
Я вот тут попробовал кое-что...
Таблица из 723705 записей, 204 колонки. Комп не супер-пупер скоростной (не сервер, а рабочий ноутбук), но более-менее все-таки
БД - PostgreSQL.
Даю команду на выборку
Таблица из 723705 записей, 204 колонки. Комп не супер-пупер скоростной (не сервер, а рабочий ноутбук), но более-менее все-таки

БД - PostgreSQL.
Даю команду на выборку
SQL |
select * from block_3120 order by random() limit 1 |
Время выборки - 20-22 секунды, при многократных повторных запусках
Делаю другую выборку, в 2 этапа. Сначала выбираю произвольную дату, а потом уже выбираю все данные, с произвольной выборкой по этой дате:
SQL |
select * from block_3120 where date_ = (select date_ from block_3120 order by random() limit 1 ) order by random() limit 1 |
Время выборки - 2-3 секунды. Также при многократных повторах.
Вывод: раз в 7-11 быстрее получилось, на пустом месте, без особых изысков. Единственное уточнение (возможно, существенное) - по дате есть индексация.
Спустя 2 минуты, 47 секунд (18.03.2009 - 16:04) nasferatu написал(а):
sergeiss, спасибо, сейчас поробуем у себя
Спустя 9 минут, 17 секунд (18.03.2009 - 16:13) nasferatu написал(а):
В моем случае это будет так.
PHP |
$result = mysql_query("SELECT id_album, foto FROM foto WHERE id=(SELECT id FROM foto ORDER BY rand() LIMIT 1)"); |
Спустя 33 секунды (18.03.2009 - 16:13) Viking написал(а):
точно
select * from big where id>=round(rand()*(select max(id) from big)) limit 1;
работает быстро, с учетом возможных пропусков id
select * from big where id>=round(rand()*(select max(id) from big)) limit 1;
работает быстро, с учетом возможных пропусков id
Спустя 10 минут, 53 секунды (18.03.2009 - 16:24) sergeiss написал(а):
Цитата (nasferatu @ 18.03.2009 - 16:13) | ||
В моем случае это будет так.
|
А разница по времени какая получилась?
Спустя 3 минуты, 29 секунд (18.03.2009 - 16:28) Viking написал(а):
Цитата |
В моем случае это будет так. PHP $result = mysql_query("SELECT id_album, foto FROM foto WHERE id=(SELECT id FROM foto ORDER BY rand() LIMIT 1)"); |
дык тут опять ордер с ранд
а мой пример почему-то неправильно работает...
Спустя 31 минута, 34 секунды (18.03.2009 - 16:59) Viking написал(а):
PHP |
$res = mysql_query("select max(id) from big"); |
вот это точно нормально работает
Спустя 3 минуты, 27 секунд (18.03.2009 - 17:03) nasferatu написал(а):
у меня и те работали.
а по времени выполнения он получше булет????
а по времени выполнения он получше булет????
Спустя 10 минут, 49 секунд (18.03.2009 - 17:14) Viking написал(а):
то что два запроса это конечно хуже, но в один корректно не получается, день сегодня такой, сами запросы работают быстро, а с order by rand однозначно медледнно
Спустя 45 минут, 33 секунды (18.03.2009 - 17:59) Sylex написал(а):
у меня вот че вышло:
SQL |
SELECT * FROM test_tab JOIN (SELECT FLOOR(RAND() * MAX(id)) AS rn from test_tab) AS tmp WHERE id>=tmp.rn LIMIT 1 |
работает
Спустя 3 минуты, 44 секунды (18.03.2009 - 18:03) Sylex написал(а):
кстати, вот наткнулся на хорошие темки
:
http://jan.kneschke.de/projects/mysql/order-by-rand
http://habrahabr.ru/blogs/mysql/54176/

http://jan.kneschke.de/projects/mysql/order-by-rand
http://habrahabr.ru/blogs/mysql/54176/
Спустя 30 минут, 2 секунды (18.03.2009 - 18:33) kirik написал(а):
Если одна запись нужна, то есть хороший пример во второй ссылке, что дал Sylex:
Цитата |
Для начала узнаем общее кол-во записей в таблице: SELECT COUNT(*) FROM tTable; Далее просто вычислим произвольное число от 0 до кол-ва записей в этой таблице rand_row = round(rand() * row_count); Теперь без проблем можно сделать выборку произвольной записи: SELECT * FROM tTable LIMIT rand_row, 1; |
А если нужна не одна, то наверное лучше кэшировать в файл все id-шники в сериализованном массиве, потом этот массив shuffle'ить и затем делать выборку нужных айдишников.. Когда же наконец сделают нормальный order by rand..

Спустя 17 часов, 3 минуты, 38 секунд (19.03.2009 - 11:37) nasferatu написал(а):
мда, этот пример, наверно, пока самый удачный

Спустя 4 часа, 14 минут, 28 секунд (19.03.2009 - 15:51) nasferatu написал(а):
протестировал
PHP |
$result = mysql_query("SELECT * FROM order by rand() limit 1"); |
время mysql: 0.003810, всего затрачено: 0.039264
а
PHP |
$result = mysql_query("SELECT * FROM foto"); |
время mysql: 0.004899, всего затрачено: 0.049555
значит, лучше использовать только один запрос (записей пока в таблице не много)
Спустя 24 минуты, 35 секунд (19.03.2009 - 16:16) Viking написал(а):
у меня в таблице 300 000 записей:
select * from big order by rand() limit 1; - 1 row in set (0.69 sec)
против:
select count(*) from big; - 1 row in set (0.00 sec)
(тестировал прямо в mysql, поэтому точность низкая)
select * from big limit 200000,1; - 1 row in set (0.06 sec)
select * from big order by rand() limit 1; - 1 row in set (0.69 sec)
против:
select count(*) from big; - 1 row in set (0.00 sec)

select * from big limit 200000,1; - 1 row in set (0.06 sec)
Цитата |
$result = mysql_query("SELECT * FROM foto"); $rand_row = rand(0,mysql_num_rows($result)); $result = mysql_query("SELECT * FROM foto LIMIT $rand_row,1"); |
так нет смысла делать, ты вытягиваешь ВСЕ записи в пхп и там считаешь их количество, по этмоу у тебя и время большое, лучше сразу посчитать как в примере kirikа
Спустя 1 час, 32 минуты, 18 секунд (19.03.2009 - 17:48) nasferatu написал(а):
0.03 получается