Для получения нескольких случайных записей из таблицы 98% программистов всегда используют всем известную конструкцию ORDER BY RAND() LIMIT xx. Для тех кто не знает как работает данная команда (которая гробит производительность) - запрос копирует выборку во временную таблицу и добавляет поле со случайным значением и после этого начинает выбирать по этому "новому" полю случайные строки. Если таблица содержит много строк - производительность просто упадет в самый низ!
Это похоже на цикл, для каждой записи мы имеем 2 переменные @count
и @limit
. @count
уменьшается на 1 для каждой просматриваемой строки, @limit
уменьшается для каждой выбранной строки:
SELECT test_value
FROM (
SELECT @count := COUNT(*) + 1, @limit := 5
FROM test_rand
) AS vars
STRAIGHT_JOIN (
SELECT r.*, @limit := @limit - 1
FROM test_rand AS r
WHERE
(@count := @count - 1)
AND RAND() < @limit / @count
) AS i
Стоит отметить, что в InnoDB таблицах такой разницы можно не заметить, так как COUNT() работает намного быстрее в MyISAM.
Такой вариант лучше использовать для таблиц с большим количеством данных, так как он основан на вероятностном подходе. Как всегда решать вам. Если в таблице 10 строк и вам нужно выбрать 1 случайную, то с этим отлично справится ORDER BY RAND(). Если в таблице несколько миллионов записей, тогда уже стоит подумать.