|
|
Знаете ли Вы, что ... | |
...нарушения правил форума наказываются. Старайтесь их не нарушать. | |
<< Предыдущий совет - Случайный совет - Следующий совет >> |
Разное/IT Всё, что не попадает в другие разделы форума и подфорумов представленных здесь организаций. Не IT темы обсуждаются в "Беседке" |
Ответить |
|
Опции темы | Опции просмотра |
14.10.2013 10:53 | #41 |
Ни к чему.
У кого еще есть варианты по рандомной выборки из базы ?) Необязательно на php, но обязательно при работе с MySQL
__________________
http://hit-season.net/ - сериалы On-Line! |
|
|
Ответить |
14.10.2013 12:39 | #42 | |
Служу Его Божественной Тени!
Сообщений: 1,671
+ 4,505
1,372/657
– 164
33/27
|
Цитата:
Да, и если выбирать нужно часто, а меняется таблица редко, то есть смысл сразу ID-шники в массив выгрузить, и потом уже по нему рандомом выбирать...
__________________
Are you my mommy? Последний раз редактировалось DarkUser; 14.10.2013 в 12:42. |
|
|
Ответить |
2 "+" от:
|
Реклама и уведомления | |
14.10.2013 13:27 | #44 | |
Google
software engineer
AKA:Y combinator
Сообщений: 418
+ 114
374/183
– 6
9/8
|
Цитата:
Поднял для экспериментов облачный сервер на selectel.ru: 8 GB RAM, 8 потоков (Xeon E5-2630@2.3 GHz), Debian 7 amd64, MySQL 5.5.31. В my.cnf поправил следующее: Код:
key_buffer_size = 128M sort_buffer_size = 64M query_cache_limit = 4M query_cache_size = 512M innodb_file_per_table innodb_buffer_pool_size = 4G innodb_log_file_size = 512M Код:
SELECT * FROM test ORDER BY RAND() LIMIT 10; Попробовал помочь планировщику, чтобы не сортировал строки целиком: Код:
SELECT test.* FROM test JOIN (SELECT id FROM test ORDER BY RAND() LIMIT 10) sub ON test.id = sub.id; Погасил MySQL, поднял PostgreSQL. Версия 9.1.9, в конфиге поправил только: Код:
shared_buffers = 4G work_mem = 64M maintenance_work_mem = 64MB Код:
SELECT * FROM test ORDER BY random() LIMIT 10; Код:
SELECT test.* FROM test JOIN (SELECT id FROM test ORDER BY random() LIMIT 10) sub ON test.id = sub.id; Кто интересовался, чем постгрес лучше — в частности вот. Причину колоссального отрыва на первом запросе легко выяснить в плане: Код:
QUERY PLAN ----------- Limit (cost=308654.61..308654.63 rows=10 width=1060) (actual time=2989.145..2989.171 rows=10 loops=1) -> Sort (cost=308654.61..311154.60 rows=999999 width=1060) (actual time=2989.141..2989.150 rows=10 loops=1) Sort Key: (random()) Sort Method: top-N heapsort Memory: 38kB -> Seq Scan on test (cost=0.00..287044.99 rows=999999 width=1060) (actual time=81.551..1435.582 rows=999999 loops=1) При достаточно равномерном распределении автоинкрементного ключа способ с выборкой N случайных ID в диапазоне min..max, наверное, самый практичный. Если с ключом проблемы, а запросы на N случайных записей ну очень важны, я бы попробовал материализовать это так: Код:
ALTER TABLE test ADD COLUMN rndkey double precision NOT NULL DEFAULT random(); CREATE INDEX test_rndkey ON test(rndkey); Код:
SELECT * FROM test WHERE rndkey > random() ORDER BY rndkey LIMIT 1; Цена такого запроса — один проход по хорошо сбалансированному индексу. На «горячих» данных — единицы миллисекунд в любой базе. Запрос с некоторой вероятностью может не вернуть данных вообще, поэтому его нужно повторять, пока не наберётся N строк. Все равно дешевле, чем full scan. Для минимизации накладных расходов по общению с базой можно завернуть в хранимку. Самый эффективный способ, пожалуй, должен быть реализован напрямую в базе, как TABLESAMPLE в SQL Server: имея карту данных на диске, выбрать некоторое количество случайных страниц указанной таблицы, и вытянуть строки оттуда — минуя индексы и всё остальное. |
|
|
Ответить |
7 "+" от:
|
14.10.2013 14:40 | #45 | |
Т.е. получается, что если mysql, то лучший способ это через помощь скриптов, а если протектед, то можно спокойно и через сам запрос решать?
Цитата:
__________________
http://hit-season.net/ - сериалы On-Line! |
||
|
Ответить |
14.10.2013 15:05 | #48 | |
Сообщений: 3,327
+ 337
892/590
– 3
31/25
|
Цитата:
Думаю Rooslan Khayrov знает об этом, и мое сообщение не ему адресовано. ;-)
__________________
404 Not Found |
|
|
Ответить |
14.10.2013 15:06 | #49 |
Служу Его Божественной Тени!
Сообщений: 1,671
+ 4,505
1,372/657
– 164
33/27
|
Если делать запрос вида Select * from table limit 1 offset N (где N - заранее сгенерированный случайный номер из [0 .. count - 1]), то - нет. А так, запрос без указания Order By обычно инвариантен и порядок строк соответствует порядку хранения данных в таблице.
__________________
Are you my mommy? |
|
Ответить |
Реклама и уведомления | |
|