- Поисковые системы
- Практика оптимизации
- Трафик для сайтов
- Монетизация сайтов
- Сайтостроение
- Социальный Маркетинг
- Общение профессионалов
- Биржа и продажа
- Финансовые объявления
- Работа на постоянной основе
- Сайты - покупка, продажа
- Соцсети: страницы, группы, приложения
- Сайты без доменов
- Трафик, тизерная и баннерная реклама
- Продажа, оценка, регистрация доменов
- Ссылки - обмен, покупка, продажа
- Программы и скрипты
- Размещение статей
- Инфопродукты
- Прочие цифровые товары
- Работа и услуги для вебмастера
- Оптимизация, продвижение и аудит
- Ведение рекламных кампаний
- Услуги в области SMM
- Программирование
- Администрирование серверов и сайтов
- Прокси, ВПН, анонимайзеры, IP
- Платное обучение, вебинары
- Регистрация в каталогах
- Копирайтинг, переводы
- Дизайн
- Usability: консультации и аудит
- Изготовление сайтов
- Наполнение сайтов
- Прочие услуги
- Не про работу
Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий
Чем order by rand() плох? :)
Он на не большом кол-ве записей тормозить вроде не должен.
Один из нормальных путей это:
1) получить MIN(id), MAX(id);
2) сгенерировать 50 штук чисел между этими значениями;
3) Сделать или 50 запросов, или сделать id = IN(число, число, число, число ....), или через UNION. Всё это ориентируясь на последовательность полученных в п.2 значений
4) полученные результаты перевести в массив, а его в свою очередь сериализовать и положить в кеш, обновлять вышеуказанным способом раз в сутки.
5) Доставать массив разсериализовывать и доставать оттуда случайным образом 5 значений, выводить их.
Моменты на которые стоит обратить внимание:
1) если в п.3 есть ещё какие-то WHERE, то обязательно нужно делать индексы, а лучше составные.
2) мы можем получить не 50, а меньше значений - так как некоторые посты могут быть удалены, в скрипте нужно учитывать это.
3) этот пункт для тех, кто может заметить, что здесь псевдослучайность - обычный пользователь врядли будет смотреть больше 10 страниц, а постоянные посетители врядли будут смотреть на случайные посты.
В целом данный способ испробован и успешно работает, а почему б ему не работать :), на сайте с несколькими десятками тысяч уников (от 30 до 80, в среднем - 40-50К), записей где-то около 5-6 тысяч. Проблемы были только один раз, поэтому я и настаиваю на составных индексах, тогда всплыла проблема как раз с этим.
p.s. общий принцип похож на описанный выше modobaks'ом.
Dreammaker, боже, как сложно...
Чем order by rand() плох?
Только тем, что он переберёт ВСЕ значения.
Лично я на базе в 400K записей юзаю следующую конструкцию:
SELECT * FROM table WHERE RAND()<0.001 ORDER BY RAND() LIMIT X,
где число 0.001 подбирается опытным путём.
Полёт нормальный. Выполнение - доли секунды.
N_MONax добавил 16.05.2009 в 04:44
Если к этому добавить кеширование и большую посещаемость (как вариант в данном случае, постоянно сохранять полученные выборки в файлах или базе, а потом "подмешивать" через раз уже "готовые" выборки) то вообще всё шоколадно будет.
Только тем, что он переберёт ВСЕ значения.
EXPLAIN SELECT * FROM dle_post WHERE RAND( ) < 0.001 ORDER BY RAND( ) LIMIT 5
1 SIMPLE dle_post ALL NULL NULL NULL NULL 4338 Using where; Using temporary; Using filesort
А ваш способ прям не просматривает все записи :D
В данном случае explain со случайными функциями не сможет оценить вероятности , поэтому лучше вызывать сразу после запроса show status like 'handler%'; . Увидите Handler_read_rnd_next равный числу строк.
show status like 'handler%';
Handler_commit 0
Handler_delete 0
Handler_discover 0
Handler_prepare 0
Handler_read_first 0
Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 5
Handler_read_rnd_next 4359
Handler_rollback 0
Handler_savepoint 0
Handler_savepoint_rollback 0
Handler_update 0
Handler_write 18
То есть, получается просматриваются все записи или почти все.
Dreammaker, Возможно. Я просто предложил свой способ.
У меня он работает в 10-тки раз быстрее, нежели order by rand(). Исследованиями мускул-запросов я никогда не занимался :)
Быстрее будет без сортировки, как уже тут предлагали.
1. Генерим рандом число в диапазоне количества записей - X.
2. В лимите говорим выводить столькото записей ( например 5) с позиции X.
ПС: не забываем про коридор из (в нашем случае 5-ти записей) т.е. диапазон генерации снижаем на кол-во выводимых записей.