.order('RANDOM()').limit(limit)виглядає акуратно, але повільний для великих таблиць, оскільки йому потрібно отримати та сортувати всі рядки, навіть якщо limitце 1 (внутрішньо в базі даних, але не в Rails). Я не впевнений у MySQL, але це відбувається в Postgres. Більше пояснень тут і тут .
Одне рішення для великих таблиць - .from("products TABLESAMPLE SYSTEM(0.5)")де 0.5кошти 0.5%. Однак я вважаю, що це рішення все ще повільне, якщо у вас є WHEREумови, які фільтрують багато рядків. Я думаю, це тому, що TABLESAMPLE SYSTEM(0.5)виберіть усі рядки до того, як WHEREзастосовуються умови.
Ще одне рішення для великих таблиць (але не дуже випадкових):
products_scope.limit(sample_size).sample(limit)
де sample_sizeможе бути 100(але не занадто великим, інакше це повільно і споживає багато пам’яті), а limitможе бути 1. Зауважте, що хоча це швидко, але це насправді не випадково, це випадково sample_sizeлише в записах.
PS: Результати Benchmark у відповідях вище не є надійними (принаймні, у Postgres), тому що деякі запити БД, які виконуються у 2-й час, можуть бути значно швидшими, ніж виконання у 1-й раз, завдяки кешу DB. І, на жаль, не існує простого способу відключити кеш в Postgres, щоб зробити ці орієнтири надійними.