![]() |
|
Модераторы: skyboy, MoLeX, Aliance, ksnk |
![]()
|
|
| Nigel |
|
|||
|
познаю мир ![]() ![]() Профиль Группа: Участник Сообщений: 515 Регистрация: 20.11.2007 Репутация: 7 Всего: 19 |
Что-то типа такого
Конечно, нужен ключ по полю id. |
|||
|
||||
| bars80080 |
|
|||
![]() прапор творюет ![]() ![]() ![]() ![]() Награды: 1 Профиль Группа: Завсегдатай Сообщений: 12022 Регистрация: 5.12.2007 Где: Königsberg Репутация: 71 Всего: 315 |
меня тут осенила гениальнейшая идея на ноб.премию
смотрю, как тут не первый раз возникают темы про случайную выборку и про то, насколько она тормознутая средствами mysql и подумалось следующее как бы мы там ни говорили про идеальность, всё равно её не существует, если мы говорим о "случайном" выборе, то на самом деле подразумеваем псевдослучайную последовательность, которая периодически повторяется, но с большим периодом. в конце концов в электронике нет генератора чистой случайности за исключением болометра итак, вместо того чтобы пользоваться rand можно сконструировать псевдослучайный режим выборки, скажем, так: условия: при всём уважении, если мы поднимаем что-то, к примеру случайные фотографии или набор новостей, то больше 20-40 смысла нет отсюда, можно ввести в таблицу поле rnd int в которое при запросах insert и update будет вноситься случайное число. далее, при необходимости случайной выборки мы средствами пхп случайно определяем два-три числовых параметра. допустим: дата, число rnd int и в какую сторону считать выше или ниже. после этого строим запрос по принципу: ... where date<$rnd_date and rnd>$rnd_int order by rnd desc limit 20 синим и красным отмечены случайные элементы. если элементов не хватает, то надо просто отсчитать в другую сторону, костыль придумать не сложно в зависимости от количества присутствующих в таблице данных и количества подобных запросов в единицу времени мы получаем примерную периодичность повторения этой псевдослучайной последовательности. имхо, это будет настолько редко, что никто и не заметит, тем более что внесение одной дополнительной записи разрушает период и полное совпадение возможно только случайно вот такое вот идея |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 75 Всего: 260 |
Nigel, однако в вырожденном случае(rand() вернуло 1) мы получим выборку из одной записи. сколько бы ни было в таблице. естественно, в реальности все может быть, но поначалу(пока в таблице данных немного) такая накладка вполне может частенько происходить: нужное количество есть, но выводятся не все.
|
|||
|
||||
| Nigel |
|
|||
|
познаю мир ![]() ![]() Профиль Группа: Участник Сообщений: 515 Регистрация: 20.11.2007 Репутация: 7 Всего: 19 |
skyboy, http://dev.mysql.com/doc/refman/5.1/en/mat...l#function_rand в неравенстве строго меньше 1.
|
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 75 Всего: 260 |
Nigel, окей. 9 записей всего. надо выбрать максимум 10 случайных. rand() возвращает 0,5. сколько записей из списка id (1,2,3,4,5,6,7,8,9) будет возвращено? готов поспорить, что 5(id: 5,6,7,8,9). Это не то, что десять требуемых, а даже не девять имеющихся.
итак, продолжим измышления. пускай, у нас значения id распределены так: 1,2,3,4,5,6,7,8,9,100 вероятность того, что floor(rand() * 100) будет больше 9 высока - 9/10. То есть вероятность 90%, что вместо хотя бы 9 значений будет получено только одно. или я что-то неверно понимаю? Добавлено через 2 минуты и 51 секунду нет, вариантов вижу два: выбрать id в клиента и средствами клиента перемешать/выбрать N требуемых или же "тот самый неэффективный запрос с order by rand()". впорчем, не все так плохо: можно поле "случайное значение для сортировки" записывать в таблицу и обновлять...эээ..ну, раз в час. тогда и индексы используются, и элементы местами меняются, да и клиенты вполне могут не заметить. |
|||
|
||||
| Nigel |
|
|||
|
познаю мир ![]() ![]() Профиль Группа: Участник Сообщений: 515 Регистрация: 20.11.2007 Репутация: 7 Всего: 19 |
Выбрать 10 записей из 9 возможных? Это как? Опечатка, видимо
skyboy, order by rand() начинает тормозить на 4-5 тыс записях, поэтому приводить в пример таблицу с 5-ю, 10-ю или 20-ю записями не коректно. Примерно из той же оперы: у меня таблица с 3-мя записями, при выборке мускул подлец индексы не использует, щас я ему форс пропишу, чтоб было как надо.
Воот, ключевое слово здесь обновлять. Если раз в час то это уже не рэндом получается, если меньше, то лишняя нагрузка, костыль имхо. Тот запрос я привел для примера, он не идеален, есть способ эффективнее. Это сообщение отредактировал(а) Nigel - 25.12.2008, 02:52 |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 75 Всего: 260 |
Nigel, сложно возразить.
Да, приведенный тобой запрос быстрее. Да, таблица с пятью записями маловероятно появится в реальном проекте. Но, с другой стороны: - если имеется значительная "дырка" в значениях поля id(массовая чистка контента портала, удаление тестовых данных), то данные, с идентификатором "до дырки" будут выбираться значительно реже тех, что "после дырки" - данные будут идти подряд(в смысле, выбираются идентификаторы, идущие подряд) - разве это больший "рэндом", чем обновление каждый час? впрочем, да. согласен. в реальном проекте разработчика должна волновать производительность запроса на 5 тысячах записей, нежели корректность работы. |
|||
|
||||
![]()
|
| Правила форума "PHP" | |
|
|
Новичкам:
Важно:
Внимание:
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | PHP: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |