Оптимизация ORDER BY RAND()

Как выбрать случайную запись из таблицы в MySQL?

Во всех учебниках и мануалах случайную запись выбирают так:

SELECT id FROM files ORDER BY rand() LIMIT 1;

Но такие запросы работают очень медленно. Посмотрим на EXPLAIN:

EXPLAIN SELECT id FROM files ORDER BY rand() LIMIT 1;

Увидим, что MySQL создает временную таблицу и использует сортировку всех данных. Такой запрос будет работать все медленнее при наполнении таблицы:

+----+-----+------+----------------------------------------------+
| id | ... | rows | Extra                                        |
+----+-----+------+----------------------------------------------+
|  1 | ... | 4921 | Using index; Using temporary; Using filesort |
+----+-----+------+----------------------------------------------+

Правильным решением будет использование индекса и избавление от ORDER BY RAND(). Для этого нужно:

  • Определить максимальное значение ID (да, такая колонка должна быть и она должна быть ключом) в таблице.
  • Получить любое случайное число от нуля до максимального ID.
  • Выбрать первую запись из таблицы, где ID больше указанного случайного числа, отсортировав ее по этой же колонке.

Если перевести все в запрос:

SELECT f.id FROM files f
	    JOIN ( SELECT RAND() * (SELECT MAX(id) FROM files) AS max_id ) AS m
	    WHERE f.id >= m.max_id
	    ORDER BY f.id ASC
	    LIMIT 1;

Как это работает

  • Во вложенном запросе мы определяем максимальное значение ID. Допустим оно будет 100000.
  • Дальше умножаем это значение на функцию RAND(). Она возвращает значение от 0 до 1. Пусть в примере будет 0.5. Тогда результат умножения будет 50000.
  • После этого это значение с помощью JOIN прибавляется в каждой строке оригинальной таблицы.
  • Фильтр f.id >= m.max_id выберет первую попавшуюся запись, ID которой будет больше 50000.
  • Поскольку мы использовали сортировку ORDER BY f.id ASC, все пропущенные записи будут иметь значение меньше 50000.
  • Это значит, что мы выбрали случайную запись из всей таблицы. Но в отличие от ORDER BY RAND(), мы использовали сортировку и фильтрацию по индексу ID (а значит эффективно).

Скорость такого запроса будет в несколько раз быстрее, чем оригинального:

mysql> SELECT id FROM files ORDER BY rand() LIMIT 1;
+-------+
| id    |
+-------+
| 72643 |
+-------+
1 row in set (0.17 sec)

Ускоренная версия:

mysql> SELECT f.id FROM files f JOIN ( SELECT rand() * (SELECT max(id) from files) AS max_id ) AS m WHERE f.id >= m.max_id ORDER BY f.id ASC LIMIT 1;
+-------+
| id    |
+-------+
| 86949 |
+-------+
1 row in set (0.00 sec)

Теперь работает быстро и не зависит от размера таблицы.

Ссылки

  • Оптимизация ORDER BY RAND()

ВКонтакте

Одноклассники

Telegram

WhatsApp

MySQL PHP random WordPress Производительность

Как использовать функцию rand() в PHP

В этом руководстве мы покажем вам, как использовать функцию rand() в языке программирования PHP.

Если вам требуется случайное значение, сгенерированное в вашем PHP-скрипте, то идеально подойдет функция rand() . Он очень прост в использовании и понимании.

В этом руководстве показано, как использовать функцию с аргументами и без аргументов. Мы также коснемся того, как можно сгенерировать случайное число с плавающей запятой.

Начиная с PHP 7.1 функция rand() использует тот же генератор случайных чисел, что и функция mt_rand() . Использование того же бэкэнда, что и mt_rand() , означает, что генерируемые случайные числа получены из генератора случайных чисел Mersenne Twister. Генератор генерирует случайные числа намного быстрее, чем средняя функция rand libc.

Не рекомендуется использовать эту функцию, если вам требуются криптографически безопасные значения. Альтернативы, такие как random_bytes() , openssl_random_pseudo_bytes() или random_int() могут использоваться в криптографических целях.

В этом руководстве предполагается, что вы используете PHP 7.4 или выше. Тем не менее, мы рекомендуем вам обновиться до последней доступной версии PHP.

Синтаксис функции PHP rand()

Синтаксис функции rand довольно прост, как вы можете видеть ниже. Ниже мы обсудим два необязательных аргумента и возвращаемое значение.

Два аргумента, min и max , должны быть целым числом. Кроме того, возвращаемое значение будет целым числом.

Указание значений для min и max ограничит генерируемое случайное значение указанными вами значениями. Например, если вам нужно случайное число от 100 до 200 (включительно), вы должны написать случайную функцию, например, rand(100, 200) .

Оба аргумента являются необязательными, и без них PHP вернет случайное значение между 0 и getrandmax() . Если вы укажете аргументы, вам нужно будет ввести оба. Если вы введете только один, вы получите сообщение об ошибке.

Важно отметить, что есть еще одна случайная функция, которую вы можете использовать в PHP, и это функция mt_rand() .

Функция mt_rand() по сути такая же, как rand() в версиях PHP 7.1 и выше. Единственная разница в том, что mt_rand() не позволяет max должен быть меньше мин .

Примеры функции rand()

Мы рассмотрим два примера использования функции rand() в PHP. В одном примере мы не будем использовать параметры, а в другом будем использовать два параметра. Мы также расскажем, как вы можете использовать rand() для генерации случайных чисел с плавающей запятой.

Без аргументов

В приведенном ниже примере мы не используем никаких аргументов при использовании PHP-функции rand. Поэтому наше число может варьироваться от 0 к значению, определенному getrandmax() .

В приведенном ниже выводе вы можете увидеть число, напечатанное при первом запуске скрипта. Каждый раз, когда вы запускаете скрипт, вы получаете другое число.

Использование аргументов

В этом примере будет использоваться 100 в качестве минимального аргумента и 200 в качестве максимального аргумента. Использование этих двух значений в качестве аргументов означает, что наше случайное число будет находиться в диапазоне от 100 до 200 (включительно).

При первом запуске было возвращено случайное число 190 . Каждый раз, когда мы запускаем скрипт PHP, PHP будет возвращать другое случайное число между 100 и 200 .

Создание случайного числа с плавающей запятой с помощью rand()

Если вам нужно число с плавающей запятой, а не целое число, вы можете добиться этого, разделив результат PHP-функции rand. В приведенном ниже примере мы делим наш результат на 1000 , чтобы получить случайное число с плавающей запятой, а не целое число.

Наш результат 1.105 , что означает, что rand() произвело целое число 1105 , которое мы затем разделили на 1000 . Конечно, вы можете повозиться с математикой, чтобы получить значения, которые вы хотите для своей программы.

Заключение

Я надеюсь, что это краткое руководство научило вас основам использования функции rand в PHP для генерации случайных чисел. Эта функция чрезвычайно полезна, когда вам нужно сгенерировать случайное число.

В PHP есть много других функций, которые могут оказаться чрезвычайно полезными для программирования вашего следующего сценария. Например, вам может понадобиться сгенерировать хэш md5 или проверить, является ли значение числовым. Я настоятельно рекомендую ознакомиться с нашими многочисленными руководствами по PHP, если вы хотите узнать больше.

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

Филиппинское песо в Южноафриканский ранд.

Преобразовать PHP/ZAR

Преобразовать PHP в ZAR на реальном обменном курсе

Количество

1000 PHP

. 30 UTC

Отслеживание курса обмена

Мы не можем отправить деньги между этими валютами

Мы работаем над этим. Подпишитесь, чтобы получать уведомления, и мы сообщим вам, как только сможем.

Get notified when we launch

  EUR GBP USD INR CAD AUD CHF MXN
1EUR 1 0.8821 1,0744 88,4392 1.46935 1.60742 0.9807 20.0222
1GBP 1.13366 1 1.21805 100.264 1.66581 1.82234 1.11178 22. 6992
1USD 0.93075 0.820984 1 82.315 1.3676 1.49611 0.9128 18.6357
1INR 0.0113072 0.00997369 0.0121485 1 0.0166142 0.0181754 0.0110891 0.226395

Beware of bad exchange rates. Банки и традиционные провайдеры часто несут дополнительные расходы, которые они перекладывают на вас, повышая обменный курс. Наша интеллектуальная технология означает, что мы более эффективны, а это означает, что вы получаете отличную ставку. Каждый раз.

Сравнить обменные курсы

Как обменять филиппинское песо на южноафриканский ранд

  • 1

    Введите сумму

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

  • 2

    Выберите валюту

    Нажмите раскрывающееся меню, чтобы выбрать валюты, между которыми вы хотите конвертировать.

  • 3

    Готово

    Наш конвертер валют покажет вам текущий курс и то, как он изменился за последний день, неделю или месяц.

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

Compare us to your bankSend money with Wise

Conversion rates Philippine Peso / South African Rand
1 PHP 0.32972 ZAR
5 PHP 1.64860 ZAR
10 PHP 3.29720 ZAR
20 PHP 6.59440 ZAR
50 PHP
16.48600 ZAR
100 PHP 32.97200 ZAR
250 PHP 82.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *