Поменяйте `table` на название вашей таблицы, и скажите есть ли прирост в скорости.
SELECT tab1.`id` FROM `table` AS tab1
JOIN
(SELECT
( RAND() * (SELECT MAX(id) FROM `table`) )
AS id )
AS tab2
WHERE tab1.id >= tab2.id
ORDER BY tab1.id ASC
LIMIT 1;
mysql> SELECT tab1.`id` FROM `image` AS tab1 JOIN (SELECT ( RAND() * (SELECT MAX(id) FROM `image`) ) AS id ) AS tab2 WHERE tab1.id >= tab2.id ORDER BY tab1.id ASC LIMIT 1;
+---------+
| id |
+---------+
| 3570920 |
+---------+
1 row in set (0.01 sec)
mysql> select id from image order by rand() limit 1 \G
*************************** 1. row ***************************
id: 1325603
1 row in set (1 min 3.43 sec)
Alex Safonov: Подразумевается что до это кода мы сделали запрос COUNT. Судя по задаче там вряд ли таблица с гепами, но даже если так, можно сформировать список для rand из массива с учётом этого. Всё от конкретики зависит. Количество записей, частота этого действия. Можно выбрать только id и из них выбрать случайный.
Alex Safonov: Для не больших баз это отличный вариант, если не заморачиваться с запросом, а делать просто кодом. К тому же не элементов, а всего лишь int значений.
Станислав Почепко: У меня под рукой есть таблица на 1 279 311. Если я делаю запрос с order by rand(), получаю ответ за 2,6с.
В таблице на 1 700 записей - 0,003с.
На маленьких таблицах нет выхлопа от использования доп. запроса.
На больших, доп. запрос выгруженный в массив отожрет много памяти.
Alex Safonov: Дак я же не спорю, что ваш код отлично работает. Я лишь подсказал, что можно использовать в данном случае, если не шарить в запросах. Я в них не силён. Я больше бизнеслогикой занимаюсь и зачастую пользуюсь различными ORM. И там есть стандартные методы для выбора рандомной записи. Возможно в этом методе что-то и реализовано в подобном стиле.
Станислав Почепко: если не шарить в запросах то лучше rand()
> Для не больших баз это отличный вариант, если не заморачиваться с запросом, а делать просто кодом
небольшие базы с rand неплохо живут.