За последние 24 часа нас посетил 19081 программист и 1635 роботов. Сейчас ищут 888 программистов ...

Рандомная выборка из таблицы

Тема в разделе "MySQL", создана пользователем inline, 15 окт 2012.

  1. inline

    inline Активный пользователь

    С нами с:
    21 май 2010
    Сообщения:
    466
    Симпатии:
    0
    Приходится много делать запросов с order by rand()
    Итого страница формируется 6-9 сек.
    Чем заменить rand() или как по другому сделать рандомную выборку из таблицы?
     
  2. Dmitriy A. Arteshuk

    Dmitriy A. Arteshuk Активный пользователь

    С нами с:
    19 янв 2012
    Сообщения:
    2.445
    Симпатии:
    66
    Адрес:
    Зеленоград
    выбирать все и разгребать выборку уже пхп а не мускулем.
     
  3. inline

    inline Активный пользователь

    С нами с:
    21 май 2010
    Сообщения:
    466
    Симпатии:
    0
    какой функцией порекомендуете?
     
  4. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.251
    Адрес:
    там-сям
    Близкие темы уже не раз обсуждались и здесь и на других форумах. Универсального решения нет, а есть рабочие подходы. Важно помнить, что ORDER BY RAND() каждый раз создает веремнную таблицу без индексов и выбирает данные из неё, поэтому всё медленно.

    Сводится всё к таким правилам:
    1. Надо попытаться уменьшить количество перебираемых записей. Как — зависит от конкретной задачи. Если область выборки будет небольшая, то вся временная таблица под RAND уместится в оперативке сервера и всё будет быстро.
    2. Скорость может увеличиться если разбить запрос на два. Сначала как-то вычисляем несколько id, затем по этим id можно выбрать нужные данные. Первую часть пытаемся как-то оптимизировать в рамках задачи.
    3. Кешировать результаты или промежуточные данные (подмножество id из которых реально нужен RAND).

    Добавлено спустя 5 минут 16 секунд:
    Если нужна ОДНА случайная запись, то может пригодиться такое правило: id записи от 1 до max(id). Вычисляем (берем из кеша) max(id) и затем по нему получаем запись. Если в нумерации возможны "дыры", то SELECT * FROM table WHERE id >=:myrandomid LIMIT 1