Апр 30

Думаю каждому web-программисту встречается задача вывода случайного элемента или нескольких элементов из таблицы .

В последнем моем проекте  как раз и появилось такое требование, по этому собрал несколько вариантов и решил описать их.

Начнем с самого простого решения:

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 _table ON _table.randomID=my_table.ID

При сравнении первого и второго варианта на выборке из 50 000 рядов были получены следующие данные:

1 вариант - примерно 1,5 сек.

2 вариант -римерно 0,001 сек.

Так что простое не всегда быстрое.

Буду благодарен за ваши отзывы и пожелания, а может быть и новые варианты выборки случайного элемента из MySQL

Что бы Ктулху не воскрес, подпишись на RSS!
Метки:, , , ,

автор: Антон \\ теги: , , , ,



Еще по этой теме:

Отзывов (8) на «Случайный элемент из MySQL таблицы»

  1. Вадим пишет:

    Этот вариант подходит только в тех случаях, когда ID-шники увеличиваются автоинкрементом и нет пропусков. Т.е. если записи иногда удаляются с базы, то подобный запрос использовать нельзя, т.к. иногда он будет возвращать пустой recordset…

  2. Вадим пишет:

    Но и эта проблема в принципе решается следующим образом:
    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

  3. Антон пишет:

    И что дает зан «>=» ?
    3 запрос у меня работает корректно на более чем 5000 записей.
    Есть пробелы между id. Мы как раз и выбираем существующие записи а потом из них берем случайный. Так что у меня все правильно.
    Если не так. То объясните и поправьте!
    Спасибо.

  4. Стас пишет:

    то что искал

  5. Вячеслав пишет:

    Третий запрос действительно выдает пустые записи, есди идентификатор с пропусками.
    Правда этот запрос помещенный в цикл до первой непустой записи все равно работает быстрее чем один SELECT * FROM table ORDER BY rand() LIMIT 1
    Так что используем его.

    Если использовать >= random_table.randomID LIMIT 1 так же возвращает пустые записи только при этом еще и тормозит жутко.

  6. Прогер пишет:

    1. Если нужно выбрать более одной рандомной записи то не работает.
    2. Если нужно задать условие то тоже не работает

  7. Юрий пишет:

    # для выбора случайной записи я использую хранимую процедуру
    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;

  8. борис пишет:

    а какой код php вставить вставить в шаблон сайта что бы из базы выдавались определенные ячейки с определенной таблицы ВЫБОРОЧНО?
    предположим там 10 записей, а пользователям показывалась всегда какая нить одна из этих 10?

Оставьте свой отзыв

Страница 1 из 11