Думаю каждому web-программисту встречается задача вывода случайного элемента или нескольких элементов из таблицы MySQL.
В последнем моем проекте как раз и появилось такое требование, по этому собрал несколько вариантов и решил описать их.
Начнем с самого простого решения:
SELECT * FROM table ORDER BY rand()
В этом примере используется специальная функция MySQL которая генерирует случайное число - RAND()
Результатом выполнения этого запроса к MySQL будет вывод всех записей таблицы в случайном порядке. Сразу возникает вопрос - как ограничить количество выводимых случайных записей? Ответ тоже простой! Используем оператор LIMIT.
Вот как будет выглядеть запрос для вывода трех случайных записей из таблицы:
SELECT * FROM table ORDER BY rand() LIMIT 1
При больших объемах таблицы (более 10 000 записей) этот запрос становится медленным и я бы советовал применять другой более сложный но быстрый запрос:
SELECT name FROM my_table JOIN ( SELECT CEIL(RAND() * ( SELECT MAX(id) FROM my_table )) AS randomID ) AS random_table ON random_table.randomID=my_table.ID
При сравнении первого и второго варианта на выборке из 50 000 рядов были получены следующие данные:
1 вариант - примерно 1,5 сек.
2 вариант -римерно 0,001 сек.
Так что простое не всегда быстрое.
Буду благодарен за ваши отзывы и пожелания, а может быть и новые варианты выборки случайного элемента из MySQL
Метки:
MySQL,
PHP,
random,
программирование,
сортировка
автор: Антон
\\ теги: MySQL, PHP, random, программирование, сортировка
17 Июл 2008 в 1:15 дп
17 Июл 2008 в 1:32 дп
SELECT rutube_id, name FROM movie JOIN (SELECT CEIL(RAND() * ( SELECT MAX(id) FROM movie )) AS randomID ) AS random_table ON movie.ID >= random_table.randomID LIMIT 1
18 Июл 2008 в 12:22 пп
3 запрос у меня работает корректно на более чем 5000 записей.
Есть пробелы между id. Мы как раз и выбираем существующие записи а потом из них берем случайный. Так что у меня все правильно.
Если не так. То объясните и поправьте!
Спасибо.
14 Окт 2008 в 6:38 пп
21 Ноя 2008 в 2:58 пп
Правда этот запрос помещенный в цикл до первой непустой записи все равно работает быстрее чем один SELECT * FROM table ORDER BY rand() LIMIT 1
Так что используем его.
02 Дек 2008 в 12:10 дп
2. Если нужно задать условие то тоже не работает
13 Ноя 2009 в 4:11 дп
CREATE PROCEDURE select_rnd()
BEGIN
START TRANSACTION;
# в следующих двух строках замените test_table на имя таблицы
SELECT FLOOR(RAND() * COUNT(*)) INTO @rnd FROM test_table;
PREPARE stmt FROM ‘SELECT * FROM test_table LIMIT ?, 1′;
EXECUTE stmt USING @rnd;
COMMIT;
END;
07 Апр 2010 в 10:55 пп
предположим там 10 записей, а пользователям показывалась всегда какая нить одна из этих 10?