Rails 5从db获取随机记录?

时间:2018-03-28 03:56:57

标签: ruby-on-rails activerecord ruby-on-rails-5

要从数据库中获取单个随机记录,我现在正在做:

User.all.sample

但是当有100000多个用户时,加载所有用户需要几秒钟,只需选择一个。

从db获取单个随机用户的最简单方法是什么?

4 个答案:

答案 0 :(得分:11)

您可以尝试以下数据库独立查询:

User.find(User.pluck(:id).sample)
[DEBUG]  (36.5ms)  SELECT `users`.`id` FROM `users`
[DEBUG] User Load (0.5ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 58229 LIMIT 1

这一个会触发两个查询,但这个查询效率很高,因为只需 37ms 即可获得单个随机用户记录。

而以下查询将采用 624.7ms

User.order("RAND()").first
[DEBUG] User Load (624.7ms)  SELECT  `users`.* FROM `users`  ORDER BY RAND() LIMIT 1

我已经检查了105510用户记录。

答案 1 :(得分:2)

您可以在表中找到最大用户 ID,并找到一个用户,其随机 ID 限制在此最大值。示例:

max_id = User.order(id: :desc).limit(1).pluck(:id).first
user = User.find_by('id > ?', rand(max_id))

这两个查询速度非常快,因为您使用的是主键 (id) 的索引。

答案 2 :(得分:2)

经过大量的试验和错误,我发现这个解决方案很有帮助并且没有错误。


Model.find(Model.ids.sample)

Model.ids 将返回数据库中所有 id 的数组。然后我们对该数组调用 sample 方法,该方法将返回列表中的随机项。

答案 3 :(得分:1)

使用 Postgresql SQLite ,使用RANDOM()

User.order("RANDOM()").first

据推测,对于带有RAND()

MySQL ,这同样适用
User.order("RAND()").first