Моё меню Общее меню Сообщество Правила форума Все прочитано
Вернуться   uForum.uz > ИКТ и телеком > Разное/IT
Сообщения за день Поиск
Знаете ли Вы, что ...
...инструкция по установке аватара описана в Правилах форума.
<< Предыдущий совет - Случайный совет - Следующий совет >>

Разное/IT Всё, что не попадает в другие разделы форума и подфорумов представленных здесь организаций. Не IT темы обсуждаются в "Беседке"


Ответить

 
Опции темы Опции просмотра
Старый 14.10.2013 10:53   #41  
Real ID Group
Аватар для Denis Shlyapnikov
Оффлайн
FreeLance
Python/PHP программист
Сообщений: 1,054
+ 886  435/275
– 35  6/6

Russian FederationОтправить сообщение для Denis Shlyapnikov с помощью Skype™Facebook
Ни к чему.

У кого еще есть варианты по рандомной выборки из базы ?)
Необязательно на php, но обязательно при работе с MySQL
__________________
http://hit-season.net/ - сериалы On-Line!
Ответить 
Старый 14.10.2013 12:39   #42  
uParty Member Known ID Group
Аватар для DarkUser
Оффлайн
Служу Его Божественной Тени!
Сообщений: 1,671
+ 4,505  1,372/657
– 164  33/27

Uzbekistan
Цитата:
Сообщение от JackDaniels Посмотреть сообщение
Второй запрос: UNION (SELECT * FROM `a` WHERE `id` = $id[0] LIMIT 1) UNION (SELECT * FROM `a` WHERE `id` = $id[1] LIMIT 1)… и так далее.
Проверяем результат, если записи по одному из ID не было (в ID бывают "дырки"), и получили меньше чем 10, добираем нужное количество запросов.
Зачем извращяться с поиском ID-шника, если можно сразу выбрать запись с нужным порядковым номером?

Да, и если выбирать нужно часто, а меняется таблица редко, то есть смысл сразу ID-шники в массив выгрузить, и потом уже по нему рандомом выбирать...
__________________
Are you my mommy?

Последний раз редактировалось DarkUser; 14.10.2013 в 12:42.
Ответить 
2 "+" от:
Реклама и уведомления
Старый 14.10.2013 13:18   #43  
Заблокирован(а)
Аватар для JackDaniels
Оффлайн
Сообщений: 18,519
+ 10,956  12,586/6,453
– 307  539/385

Vatican City State
Цитата:
Сообщение от DarkUser Посмотреть сообщение
Зачем извращяться с поиском ID-шника, если можно сразу выбрать запись с нужным порядковым номером?
Разве перед получением строки по порядковому номеру ненужно сортировать таблицу по какому-то из признаков?
Ответить 
Старый 14.10.2013 13:27   #44  
Real ID Group
Аватар для Rooslan Khayrov
Оффлайн
Google
software engineer
AKA:Y combinator
Сообщений: 418
+ 114  374/183
– 6  9/8

Switzerland
Цитата:
array_push($sql, "('" . mysql_real_escape_string($this->randText(120)) . "', '" . mysql_real_escape_string($this->randText()) . "', " . $this->randNum(0, 10000) . ", " . $this->randNum(0, 10000) . ", " . $time . ", " . $time . ")");
Мои глаза... Генерация SQL конкатенацией строк до сих пор в моде?

Поднял для экспериментов облачный сервер на 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;
Время выполнения 9-11 сек.
Попробовал помочь планировщику, чтобы не сортировал строки целиком:
Код:
SELECT test.* FROM test JOIN
(SELECT id FROM test ORDER BY RAND() LIMIT 10) sub
ON test.id = sub.id;
800-1000 мс, куда лучше.

Погасил MySQL, поднял PostgreSQL. Версия 9.1.9, в конфиге поправил только:
Код:
shared_buffers = 4G
work_mem = 64M
maintenance_work_mem = 64MB
Создал базу с такой же схемой и залил те же самые данные, что и в MySQL.
Код:
SELECT * FROM test ORDER BY random() LIMIT 10;
1200-1300 мс.
Код:
SELECT test.* FROM test JOIN
(SELECT id FROM test ORDER BY random() LIMIT 10)
sub ON test.id = sub.id;
600-650 мс
Кто интересовался, чем постгрес лучше — в частности вот.

Причину колоссального отрыва на первом запросе легко выяснить в плане:
Код:
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)
Для запросов вида ORDER BY ... LIMIT N, где N << count(*) постгрес использует потоковый алгоритм с приоритетной очередью (bounded heap), в результате чего в плане доминируют затраты на sequential scan, а сортировка обходится минимальной памятью.

При достаточно равномерном распределении автоинкрементного ключа способ с выборкой 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;
(Не LIMIT N потому что в таком случае в выборке рядом всегда будут оказываться одни и те же записи. В принципе, решаемо регулярным обновлением колонки с перестройкой индекса — смотря что нам важнее).
Цена такого запроса — один проход по хорошо сбалансированному индексу. На «горячих» данных — единицы миллисекунд в любой базе. Запрос с некоторой вероятностью может не вернуть данных вообще, поэтому его нужно повторять, пока не наберётся N строк. Все равно дешевле, чем full scan. Для минимизации накладных расходов по общению с базой можно завернуть в хранимку.

Самый эффективный способ, пожалуй, должен быть реализован напрямую в базе, как TABLESAMPLE в SQL Server: имея карту данных на диске, выбрать некоторое количество случайных страниц указанной таблицы, и вытянуть строки оттуда — минуя индексы и всё остальное.
Ответить 
Старый 14.10.2013 14:40   #45  
Real ID Group
Аватар для Denis Shlyapnikov
Оффлайн
FreeLance
Python/PHP программист
Сообщений: 1,054
+ 886  435/275
– 35  6/6

Russian FederationОтправить сообщение для Denis Shlyapnikov с помощью Skype™Facebook
Т.е. получается, что если mysql, то лучший способ это через помощь скриптов, а если протектед, то можно спокойно и через сам запрос решать?

Цитата:
Мои глаза... Генерация SQL конкатенацией строк до сих пор в моде?
Да фиг его знает, что сейчас в моде. Я уже забыл кодла последний раз писал нативно, сейчас в основном фреймворки yii, kohana. Поэтому, как вспомнил так и записал ))
__________________
http://hit-season.net/ - сериалы On-Line!
Ответить 
Старый 14.10.2013 14:54   #46  
Аватар для spykee
Оффлайн
дом
Сообщений: 5,817
+ 1,272  1,679/1,120
– 203  271/231

Uzbekistan
Oracle

Случайная 10 выборка из более 60 миллионов записей без доп массивов, временных таблиц, одним селектом занял 16-20 сек.

А если известны значения мах и мин значений ключа таблицы то - 0.5 сек.
Ответить 
"+" от:
Старый 14.10.2013 15:02   #47  
Заблокирован(а)
Аватар для JackDaniels
Оффлайн
Сообщений: 18,519
+ 10,956  12,586/6,453
– 307  539/385

Vatican City State
Цитата:
Сообщение от spykee Посмотреть сообщение
Случайная 10 выборка из более 60 миллионов записей без доп массивов, временных таблиц, одним селектом занял 16-20 сек
Если у вас интернет-магазин и в секунду страничку со случайным товаром дергает 100-200 человек, то такой Селект прибьет сервер и разгонит клиентов.
Ответить 
Старый 14.10.2013 15:05   #48  
Аватар для shumbola
Оффлайн
Сообщений: 3,327
+ 337  892/590
– 3  31/25

Uzbekistan
Цитата:
Сообщение от Rooslan Khayrov Посмотреть сообщение
Самый эффективный способ, пожалуй, должен быть реализован напрямую в базе, как TABLESAMPLE в SQL Server: имея карту данных на диске, выбрать некоторое количество случайных страниц указанной таблицы, и вытянуть строки оттуда — минуя индексы и всё остальное.
Зависит от задачи, TABLESAMPLE не дает действительно случайных результатов. Прежде чем использовать TABLESAMPLE, изучайте область применения.
Думаю Rooslan Khayrov знает об этом, и мое сообщение не ему адресовано. ;-)
__________________
404 Not Found
Ответить 
Старый 14.10.2013 15:06   #49  
uParty Member Known ID Group
Аватар для DarkUser
Оффлайн
Служу Его Божественной Тени!
Сообщений: 1,671
+ 4,505  1,372/657
– 164  33/27

Uzbekistan
Цитата:
Сообщение от JackDaniels Посмотреть сообщение
Разве перед получением строки по порядковому номеру ненужно сортировать таблицу по какому-то из признаков?
Если делать запрос вида Select * from table limit 1 offset N (где N - заранее сгенерированный случайный номер из [0 .. count - 1]), то - нет. А так, запрос без указания Order By обычно инвариантен и порядок строк соответствует порядку хранения данных в таблице.
__________________
Are you my mommy?
Ответить 
Реклама и уведомления
Старый 14.10.2013 15:08   #50  
Аватар для spykee
Оффлайн
дом
Сообщений: 5,817
+ 1,272  1,679/1,120
– 203  271/231

Uzbekistan
Цитата:
Сообщение от JackDaniels Посмотреть сообщение
Если у вас интернет-магазин и в секунду страничку со случайным товаром дергает 100-200 человек, то такой Селект прибьет сервер и разгонит клиентов.
Нет уж.. это ж был пример выборки из всех записей.. а так обычно выборки делаются только из части всех записей.
Ответить 
Ответить




Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Advertisement System V2.5 By Branden
OOO «Единый интегратор UZINFOCOM»


Новые 24 часа Кто на форуме Новички Поиск Кабинет Все прочитано Вверх