.order('RANDOM()').limit(limit)sieht ordentlich aus, ist aber für große Tabellen langsam, da alle Zeilen abgerufen und sortiert werden müssen, auch wenn sie limit1 sind (intern in der Datenbank, aber nicht in Rails). Ich bin mir bei MySQL nicht sicher, aber das passiert in Postgres. Weitere Erklärungen hier und hier .
Eine Lösung für große Tische ist .from("products TABLESAMPLE SYSTEM(0.5)")wo 0.5Mittel 0.5%. Ich finde jedoch, dass diese Lösung immer noch langsam ist, wenn Sie WHEREBedingungen haben, die viele Zeilen herausfiltern. Ich denke, das liegt daran, dass TABLESAMPLE SYSTEM(0.5)alle Zeilen zuvor abgerufen wurdenWHERE Bedingungen zutreffen.
Eine andere Lösung für große Tabellen (aber nicht sehr zufällig) ist:
products_scope.limit(sample_size).sample(limit)
wo sample_sizekann sein 100(aber nicht zu groß, sonst ist es langsam und verbraucht viel Speicher) und limitkann sein 1. Beachten Sie, dass dies zwar schnell ist, aber nicht wirklich zufällig, sondern sample_sizenur innerhalb von Datensätzen zufällig .
PS: Benchmark-Ergebnisse in den obigen Antworten sind nicht zuverlässig (zumindest in Postgres), da einige DB-Abfragen, die zum zweiten Mal ausgeführt werden, dank des DB-Caches erheblich schneller sein können als zum ersten Mal. Und leider gibt es keine einfache Möglichkeit, den Cache in Postgres zu deaktivieren, um diese Benchmarks zuverlässig zu machen.