ActiveRecord 如何高效地获取随机 records

ActiveRecord 并没有直接提供随机获取的接口,有以下几种方法可以实现。

初级

Model.all.sample(n)

返回 Model 的所有 records ,浪费带宽,浪费内存,效率奇差,无节操。

进阶

ids = Model.pluck(:id).sample(n)
Model.where(id: ids)

先返回 Model 的所有 records 的 id ,然后随机选择 n 个,再次用 where 请求数据;效率不错,很有节操了。

装逼

数据库本身通常都提供 random 的语句,结合 ActiveRecord 的 order 可以用于获取随机 records :

# mysql
Model.order("RAND()").first(n)
# PostgreSQL and sqlite
Model.order("RANDOM()").first(n)

看起来很牛逼的样子,只需要因此 DB query ,但是违背了 ActiveRecord 的 database-agnostic 原则,而且数据库本身的 RANDOM 实现的效率并不高。

装逼也要有境界

尽管数据库的 random 语句各有不同,但 randumb-Adds ability to pull back random records from Active Record 封装了不同数据库的 random ,如果感兴趣,可以尝试使用这个库。

如果只随机选择一个 record

如果只想随机选择一个 record ,这种方法也是一个可选项:

offset = rand(Model.count)
Model.offset(offset).first

结论

因此,看起来进阶的方法是最靠谱的:

ids = Model.pluck(:id).sample(n)
Model.where(id: ids)

达到了各方面平衡。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值