Dan*_*uis 4 optimization activerecord ruby-on-rails
我有一个ActiveRecord模型Language,有列id和short_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)
但我不确定这是否会浪费时间/内存/处理.
我的问题是双重的:
请注意,出于我的特定目的,n约为200.
在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并查看该特定调用的数据库号.您可以调整查询并查看它如何影响日志中的性能.这应该给你一个粗略的性能估计.
同意之前的回答,但如果你绝对必须,你可以试试这个
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)