Форум успешных вебмастеров - GoFuckBiz.com

  Форум успешных вебмастеров - GoFuckBiz.com > Бизнес-решения > Скрипты, программы и технические решения
Дата
USD/RUB58.8640
BTC/USD0.0000
Скрипты, программы и технические решения Обсуждаем скрипты, программы и новые технологии.

Закрытая тема
Опции темы Опции просмотра
Старый 30.09.2011, 00:17   #1
rushter
Senior Member
 
Регистрация: 28.11.2009
Сообщений: 1,804
Бабло: $299365
По умолчанию Случайная выборка mysql

Кто-нибудь знает как можно оптимизировать получение случайных записей в mysql ?
Цитата:
SELECT * FROM `ai` ORDER BY RAND() LIMIT 0,10;
Не реально долго работает при 15 млн записей. В общем нужна случайная выборка не прогружая всё в память, может быть есть какие-то спец субд для этого ?
rushter вне форума  
Старый 30.09.2011, 00:25   #2
Юнга
white powder
 
Аватар для Юнга
 
Регистрация: 29.04.2007
Сообщений: 2,649
Бабло: $351080
По умолчанию

делал для MSSQL, но суть одинакова - если есть индексное поле упорядоченное, от 1 до 15.000.000 - рандомно сгенерить любых чисел в этом промежутке, и потом просто по индексу вытащить.
если есть разрывы - то с запасом сделать список.
__________________
господин мойва любит вас
Юнга на форуме  
Старый 30.09.2011, 00:29   #3
Юнга
white powder
 
Аватар для Юнга
 
Регистрация: 29.04.2007
Сообщений: 2,649
Бабло: $351080
По умолчанию

второй вариант - случайный сдвиг (SKIP) туда-сюда по базе.
__________________
господин мойва любит вас
Юнга на форуме  
Старый 30.09.2011, 01:02   #4
Revolver
Особый статус
 
Регистрация: 18.07.2007
Сообщений: 73
Бабло: $2005
По умолчанию

Рекомендую для очень быстрого поиска по MySQL с любым набором параметров использовать Sphinx. Очень шустрая технология.
__________________
Покупаю сайты
Revolver вне форума  
Старый 30.09.2011, 01:11   #5
Drunk Monk
Je suis moine ivre
 
Аватар для Drunk Monk
 
Регистрация: 03.03.2009
Сообщений: 15,217
Бабло: $797160072
По умолчанию

Или шафли пыхой результат
__________________
EssayPartner.com. Партнерка по эссе трафу.
Drunk Monk вне форума  
Старый 30.09.2011, 01:21   #6
dealer
me gusta
 
Аватар для dealer
 
Регистрация: 01.06.2009
Сообщений: 729
Бабло: $131031
По умолчанию

ебанулся я. потерто.

Последний раз редактировалось dealer; 30.09.2011 в 01:30.
dealer вне форума  
Старый 30.09.2011, 01:27   #7
dveredel
Читатель
 
Аватар для dveredel
 
Регистрация: 23.11.2007
Сообщений: 422
Бабло: $48745
По умолчанию

Мда, конечно советовать Сфинкс для решения классической задачи "оптимизация рандомной выборки из огромной таблицы по айди", это либо непонимание задачи, либо сфинкса )

Можно сделать не очень красиво но все по честному, быстро и только мускулом -- т.е. сразу в одном запросе, а не в цикле кучу запросов из кода посылать.
Только вот запрос придется собирать скриптом в количестве равном требуемым строкам (ибо лимит там уже не поставишь).

Соотв выборка идет по числовому\автоинкрементному индексному (без индекса даже не думать) полю с поддержкой "разрывов" в айдишнике:
Код:
SET @max:=(SELECT MAX(id) FROM table_name);

(SELECT * FROM table_name
WHERE id >= ROUND(@max*RAND()) ORDER BY id LIMIT 1)
UNION
(SELECT * FROM table_name
WHERE id >= ROUND(@max*RAND()) ORDER BY id LIMIT 1)
UNION
(SELECT * FROM table_name
WHERE id >= ROUND(@max*RAND()) ORDER BY id LIMIT 1)
/* ... Тут повторяем всю байду столько раз сколько в итоге строк надо,
 в конце юнион уже не нужен если чо ... */ 
ORDER BY id
dveredel вне форума  
Старый 30.09.2011, 02:17   #8
NTллигент
Senior Member
 
Аватар для NTллигент
 
Регистрация: 23.04.2007
Адрес: Leopolis
Сообщений: 363
Бабло: $71360
По умолчанию

Цитата:
Сообщение от rushter Посмотреть сообщение
Кто-нибудь знает как можно оптимизировать получение случайных записей в mysql ?

Не реально долго работает при 15 млн записей. В общем нужна случайная выборка не прогружая всё в память, может быть есть какие-то спец субд для этого ?
Тоже с таким сталкивался. Решилось тем, что нужное количество айдишников генерилось до запроса к БД, например в пыхе. А дальше уже
SELECT * FROM `ai`WHERE id IN (randomID1, randomID2, randomID3...)
NTллигент вне форума  
Старый 30.09.2011, 03:17   #9
chesser
автоматизирую интернеты
 
Аватар для chesser
 
Регистрация: 05.07.2009
Адрес: chesser.ru
Сообщений: 3,382
Бабло: $470735
По умолчанию

так это классическая задача
ORDER BY RAND() - при большом кол-ве данных это пиздец, да. На мелких пох.

Основная идея такая: нет ничего быстрее чем SELECT id FROM tbl WHERE id=100500, при условии, что id уник кей
если нужно несколько записей, то: ....WHERE id IN (100500, 500100, 1, 5, 100, 500)

Придумываем такой алгоритм:
- вводится уникальный числовой индекс, лучше primary key
- генерируется случайное число в диапазоне этого индекса и делает WHERE id=$randnum или WHERE id IN ()

генерация рандома может быть как на стороне сервера(mysql), так и на стороне клиента (php). Вариант с сервером более правильный.

Но будут проблемы: при частом обновлении таблицы возникнут проблемы из-за дыр в индексе. Их можно обойти разными способами:
можно заранее пытаться выбрать записей больше чем нужно, и если каких-то сгенерированных индексов не будет - то ничего страшно, раз все равно выбираем с запасом
можно выбирать впритык, и если не хватило, то добирать(делать sql запрос повторно, что не очень). Такой вариант у меня шпарит 120к/с на 100кк записей, но у меня прореженность индекса почти нулевая.

есть еще вариант с LIMIT 1, описанный dveredel - там фишка в том, что не надо точно подбирать id, но и расход памяти больше. Меня он не устроил в свое время, в том числе из-за невозможности использовать хеш-индексы. А они быстрее обычных b-tree

Вот тут еще толково описано:
http://sqlinfo.ru/forum/viewtopic.php?pid=11355#p11355
__________________
USA и NL серверы и VPS | wiki | блог | Drupal | NginxТДС
Ave, Google, morituri te salutant! © chesser
chesser вне форума  
Старый 30.09.2011, 08:16   #10
chesser
автоматизирую интернеты
 
Аватар для chesser
 
Регистрация: 05.07.2009
Адрес: chesser.ru
Сообщений: 3,382
Бабло: $470735
По умолчанию

еще добавлю

когда придешь к решению на индексе и если у тебя там не хеш-индексы, а обычные, то надо проверить системную переменную mysql: key_buffer_size, возможно ее нужно увеличить. (хеш-индексы так и так будут в памяти)
А то когда индекс не входит в буфер и читается с диска - это печально
__________________
USA и NL серверы и VPS | wiki | блог | Drupal | NginxТДС
Ave, Google, morituri te salutant! © chesser
chesser вне форума  
Закрытая тема



Опции темы
Опции просмотра