Mir*_*318 6 activerecord ruby-on-rails ruby-on-rails-5
要从db获取单个随机记录,我目前正在做:
User.all.sample
但是当有100000多个用户时,只需要几秒钟就可以加载它们,只需选择一个.
从db中加载单个随机用户的最简单方法是什么?
Gan*_*esh 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
Run Code Online (Sandbox Code Playgroud)
这个会触发两个查询,但这个查询性能很高,因为只需37毫秒即可获得单个随机用户记录.
而以下查询大约需要624.7ms
User.order("RAND()").first
[DEBUG] User Load (624.7ms) SELECT `users`.* FROM `users` ORDER BY RAND() LIMIT 1
Run Code Online (Sandbox Code Playgroud)
我已经检查了105510用户记录.
经过大量的试验和错误后,我发现这个解决方案很有帮助并且没有错误。
Model.find(Model.ids.sample)
Run Code Online (Sandbox Code Playgroud)
Model.ids将返回数据库中所有 id 的数组。然后我们调用sample该数组上的方法,该方法将返回列表中的随机项目。
使用Postgresql或SQLite,使用RANDOM():
User.order("RANDOM()").first
Run Code Online (Sandbox Code Playgroud)
想必同样会为工作的MySQL与RAND()
User.order("RAND()").first
Run Code Online (Sandbox Code Playgroud)
您可以在表中找到最大用户 ID,并根据限制为该最大值的随机 ID 查找用户。例子:
max_id = User.order(id: :desc).limit(1).pluck(:id).first
user = User.find_by('id > ?', rand(max_id))
Run Code Online (Sandbox Code Playgroud)
这两个查询速度非常快,因为您使用主键 (id) 索引。
| 归档时间: |
|
| 查看次数: |
2486 次 |
| 最近记录: |