Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

[mySql] получение случайной записи.

274
24 мая 2011 года
Lone Wolf
1.3K / / 26.11.2006
и так.
1. Есть таблица со списком ссылок, у каждой ссылки - автор(ФК на таблицу юзеров)
2. Таблица юзеров
3. Таблица друзей(ФК-ФК от юзеров). Связь многие ко многим замкнутая на ожну таблицу

Задача.
Вытащить СЛУЧАЙНУЮ ссылку пренадлежащую СЛУЧАЙНОМУ другу.

Вариант вытащить просто случайную ссылку из тех, что принадлежат друзьям - не походит, так как чем большу у человека ссылокЮ тем выше вероятность выпадения его ссылки. А нужно что бы, вероятность выпадения каждого друга была одинакова.

Гугл помог найти только ну ООЧЕНЬ не оптимальный вариант с group by и двумя ORDER BY RAND() - что при большом кол-ве записей = заднице.

Вобщем, кто что подскажет.
Может какаю-то часть оптимальнее вынести на ПХП?
274
24 мая 2011 года
Lone Wolf
1.3K / / 26.11.2006
ну первую ссылку читал. интерестно - но не очень привлекательно.. минусы описаны в первом же коменте..
тем более есть вероятность вобще получение пустого результата, так как у меня есть еще условия для выборки.

две остальных.. LIMIT БОЛЬШОЕ_ЧИСЛО, 1 - ИМХО не сильно лучше ORDER BY RAND()

Ну а гугл, как я писал выдает чаще этот самый ордер.

Конечно я продолжаю копатся.. просто времени мало, так что надеюсь еще и на вашу помощь
13
24 мая 2011 года
RussianSpy
3.0K / / 04.07.2006
Особо много вариантов тут нет и почти все я привел вам ссылками.
еще есть варианты с хранимой процедурой - рандомом берем число от 1 до максимального значения ID - вытаскиваем запись с таким ID
основным минусом будет то, что если присутствуют дыры (несуществующие ID внутри интервала), то такой способ не подходит
сколько у вас там записей в базе ? миллиарды?
274
24 мая 2011 года
Lone Wolf
1.3K / / 26.11.2006
Цитата: RussianSpy
Особо много вариантов тут нет и почти все я привел вам ссылками.
еще есть варианты с хранимой процедурой - рандомом берем число от 1 до максимального значения ID - вытаскиваем запись с таким ID
основным минусом будет то, что если присутствуют дыры (несуществующие ID внутри интервала), то такой способ не подходит
сколько у вас там записей в базе ? миллиарды?



Нет. Записей пока не много. около 10к на 1.5к юзерей. Но проэкт еще не запущен на полную мощность. так что смею ожикдать около 100к, хотя бы в очень ближайшем будущем.

Также дыры - будут, хотя бы потому что мне не просто случайная запись нужна, а случайная запись с where условием. так что даже 1ый линк не особо поможет..

Да и главный вопрос был не насколько, как оптимальней получит случайную запись, а как получить случайную запись по критерию, который тоже случаен.

т..е выбрать случайного юзера(друга) и случайную запись созданую им.

13
25 мая 2011 года
RussianSpy
3.0K / / 04.07.2006
100к и даже 1000к это не объем
не вижу причин беспокоится на вашем месте

поясните насчет случайного критерия
274
25 мая 2011 года
Lone Wolf
1.3K / / 26.11.2006
Цитата: RussianSpy
100к и даже 1000к это не объем
не вижу причин беспокоится на вашем месте

поясните насчет случайного критерия



В первом же посте написано
Вобщем нужно

 
Код:
SELECT f.fuid FROM friends f WHERE f.uid=CONST  ORDER BY RAND() LIMIT 1
- RANDOM_FRIEND_ID
 
Код:
SELECT * FROM links l WHERE l.uid=RANDOM_FRIEND_ID ORDER BY RAND() LIMIT 1


И вопрос как лучше. Отдельными двумя запросами? Или вобще как-то подругому.
13
25 мая 2011 года
RussianSpy
3.0K / / 04.07.2006
Первый запрос вам не нужен. Вам нужен только второй.
274
25 мая 2011 года
Lone Wolf
1.3K / / 26.11.2006
Цитата: RussianSpy
Первый запрос вам не нужен. Вам нужен только второй.



Эт почему?

13
25 мая 2011 года
RussianSpy
3.0K / / 04.07.2006
А зачем? Разве не все записи в таблице links имеют uid из таблицы friends? Там разве есть какие-то другие uid?
274
25 мая 2011 года
Lone Wolf
1.3K / / 26.11.2006
юид-то имеют, но толку от него? Не каждій пользователь мой друг. из 1000 юзеров мне надо случайный из 10ти.
13
25 мая 2011 года
RussianSpy
3.0K / / 04.07.2006
Ну тогда просто объедините в один запрос - будет работать быстрее чем два отдельных. В любом случае на таком количестве записей вам не о чем беспокоится и просто используйте стандартные решения
274
25 мая 2011 года
Lone Wolf
1.3K / / 26.11.2006
хм.. проверил..

совсем не быстрее..если каждый отдельно, на теперешнем обьеме - довольно быстро, то обьеденыый почти 0.5 сек
да, и с какого обьема можно начать беспокоится..?
277
25 мая 2011 года
arrjj
1.7K / / 26.01.2011
Попробуй так:
 
Код:
SELECT l.* FROM (SELECT  fuid FROM friends WHERE uid=CONST  ORDER BY RAND() LIMIT 1) AS a JOIN links l ON l.uid=a.fuid ORDER BY rand() LIMIT 1;
13
25 мая 2011 года
RussianSpy
3.0K / / 04.07.2006
Значит неверно объединили
проверьте на какие поля выставлены индексы... учитывая что это mysql проверьте какой engine используется для базы. Беспокоиться стоит тогда, когда начнет явно тормозить. Я не знаю архитектуру вашего проекта, но почти уверен, что до 200-500 тысяч записей можно смело ни о чем не беспокоится.
277
25 мая 2011 года
arrjj
1.7K / / 26.01.2011
имхо тормозить будет только на пользователях у которых больше 200-500 тыс друзей (или линков) тогда order by rand() будет временную таблицу долго ворочить.
12
28 мая 2011 года
alekciy
3.0K / / 13.12.2005
Цитата: RussianSpy
Ну тогда просто объедините в один запрос - будет работать быстрее чем два отдельных.


Не всегда. В контексте MySQL с InnoDB два запроса отработают чуть быстрее, чем один с JOIN-ом. Но в контексте сетевого приложения один запрос может быть выгоднее ввиду меньших накладных сетевых расходов.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог