从ActiveRecord模型获取ID列表的最佳实践

Dan*_*uis 4 optimization activerecord ruby-on-rails

我有一个ActiveRecord模型Language,有列idshort_code(还有其他列,但它们与此问题无关).我想创建一个方法,给出一个短代码列表,并返回一个ID列表.我不关心关联,我只需要一个看起来像[1,2,3,...]的数组.

我的第一个想法是做类似的事情

def get_ids_from_short_codes(*short_codes)
  Language.find_all_by_short_code(short_codes.flatten, :select => 'id').map(&:id)
end
Run Code Online (Sandbox Code Playgroud)

但我不确定这是否会浪费时间/内存/处理.

我的问题是双重的:

  1. 有没有办法运行ActiveRecord查找只返回某个表列的数组而不是实例化对象?
  2. 如果是这样,实际上是否值得收集长度为n的数组而不是实例化n个 ActiveRecord对象?

请注意,出于我的特定目的,n约为200.

ant*_*ome 8

在Rails 3.x中,您可以使用pluck从请求的字段返回值的方法,而无需实例化对象来保存它们.

这会给你一系列ID:

Language.where(short_code: short_codes.flatten).pluck(:id)
Run Code Online (Sandbox Code Playgroud)

我应该提一下,在Rails 3.x中,你一次只能拔一列,但在Rails 4中你可以传递多列来进行挖掘.

顺便说一句,这是类似问题类似答案


小智 6

老实说,200条记录,我不担心.当你获得2000,200或200,000条记录时 - 那么你可以担心优化.

确保您的表中包含short_code索引.

如果您仍然关注性能,请查看development.log并查看该特定调用的数据库号.您可以调整查询并查看它如何影响日志中的性能.这应该给你一个粗略的性能估计.


ale*_*dev 5

同意之前的回答,但如果你绝对必须,你可以试试这个

sql = Language.send(:construct_finder_sql, :select => 'id', :conditions => ["short_code in (?)", short_codes])
Language.connection.select_values(sql)
Run Code Online (Sandbox Code Playgroud)

虽然有点难看,但它不会创建内存中的对象.


小智 5

如果您正在使用关联,则可以直接从ActiveRecord获取原始ID.例如.:

class User < ActiveRecord::Base
  has_many :users
end

irb:=> User.find(:first).user_ids
irb:>> [1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)