Как я могу оптимизировать РЭНД ORDER BY MySQL () функция?

  1. Bob должен отредактировать FooBar.java
  2. John, проверили его для редактирования
  3. , Bob редактирует свою локальную копию так или иначе и сохраняет ее как FooBar.java.bak
  4. , Когда John проверяет его в, Bob проверяет его
  5. , Bob копирует FooBar.java.bak по нему и проверяет его в
  6. , John добирается, чтобы повторно реализовать его функцию

, я видел, что он происходит снова и снова. Разработчики делают это, потому что этот процесс является раздражающим:

  1. Bob должен отредактировать FooBar.java
  2. John, проверили его для редактирования
  3. , Bob должен ожидать, вертя его ползунки, пока John не сделан

, Пессимистическая блокировка чувствует себя подобно любительскому часу, извините.

88
задан Benjamin 16 February 2016 в 21:02
поделиться

3 ответа

Попробуйте следующее:

SELECT  *
FROM    (
        SELECT  @cnt := COUNT(*) + 1,
                @lim := 10
        FROM    t_random
        ) vars
STRAIGHT_JOIN
        (
        SELECT  r.*,
                @lim := @lim - 1
        FROM    t_random r
        WHERE   (@cnt := @cnt - 1)
                AND RAND(20090301) < @lim / @cnt
        ) i

Это особенно эффективно для MyISAM (поскольку COUNT (*) мгновенно), но даже в InnoDB он в 10 раз эффективнее, чем ORDER BY RAND () .

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

Подробнее см. в этой статье в моем блоге:

Обновление:

Если вам нужно выбрать только одну случайную запись,

67
ответ дан 24 November 2019 в 07:37
поделиться

Это зависит от того, насколько случайным вы должны быть. Решение, которое вы связали, работает очень хорошо, IMO. Если у вас нет больших пробелов в поле идентификатора, оно все равно будет довольно случайным.

Однако вы сможете сделать это в одном запросе, используя это (для выбора одного значения):

SELECT [fields] FROM [table] WHERE id >= FLOOR(RAND()*MAX(id)) LIMIT 1

Другие решения:

  • Добавить постоянное поле с плавающей запятой, называемое random , в таблицу и заполнять ее случайными числами. Затем вы можете сгенерировать случайное число в PHP и выполнить «SELECT ... WHERE rnd> $ random»
  • Захватить весь список идентификаторов и кэшировать их в текстовом файле. Прочтите файл и выберите из него случайный идентификатор.
  • Сохраните результаты запроса в виде HTML и сохраните их в течение нескольких часов.
13
ответ дан 24 November 2019 в 07:37
поделиться

Вот как бы я это сделал:

SET @r := (SELECT ROUND(RAND() * (SELECT COUNT(*)
  FROM    accomodation a
  JOIN    accomodation_category c
    ON (a.ac_category = c.acat_id)
  WHERE   a.ac_status != 'draft'
        AND c.acat_slug != 'vendeglatohely'
        AND a.ac_images != 'b:0;';

SET @sql := CONCAT('
  SELECT  a.ac_id,
        a.ac_status,
        a.ac_name,
        a.ac_status,
        a.ac_images
  FROM    accomodation a
  JOIN    accomodation_category c
    ON (a.ac_category = c.acat_id)
  WHERE   a.ac_status != ''draft''
        AND c.acat_slug != ''vendeglatohely''
        AND a.ac_images != ''b:0;''
  LIMIT ', @r, ', 1');

PREPARE stmt1 FROM @sql;

EXECUTE stmt1;
1
ответ дан 24 November 2019 в 07:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: