我的Ruby模型有 export 方法
class InfoVoucher < ActiveRecord::Base
include ActiveModel::Serializers::JSON
default_scope { order('voucher_created_at DESC') }
def attributes
instance_values
end
def self.export(data, options = {})
column_names = ["..","..","..","..",..]
exported_col_names = ["Solicitud", "Inicio", "Final", "Duracion", "Pasajero", "Unidades", "Recargo", "Propina", "Costo", "Centro de costo", "Origen", "Destino", "Proyecto", "Conductor", "Placas"]
CSV.generate(options) do |csv|
csv << exported_col_names
data.each do |row_export|
csv << row_export.attributes['attributes'].values_at(*column_names)
end
end
end
end
这样可行,但是对于非常大的文件或查询,导出需要很长时间
起初我认为这是因为查询再次运行(一次用于HTML渲染,然后再次用于导出)但事实证明,避免再次运行查询以进行导出并没有提高速度 - How to reuse the query result for faster export to csv and xls without using global or session variable
在某些语言中,连接是一项非常昂贵的任务,特别是 csv 变量与导出的整个文件的内容连接,逐个记录
数据是在带有过滤器的where方法之后从ActiveRecord继承的模型的结果
@filters = {}
@filters['email_enterprise'] = session[:enterprise_email] ;
# Add the selected filters
if (params[:f_passenger].to_s != '')
@filters['id_passenger'] = params[:f_passenger] ;
end
if (session[:role] == 2)
@filters['cost_center'] = session[:cc_name]
end
# Apply the filters and store them in the MemoryCache to make them available when exporting
@last_consult = InfoVoucher.where(@filters)
如何改善这一点以使其尽可能高效
答案 0 :(得分:0)
使用庞大的数据集时,尝试尽可能少地创建对象,并根据需要从数据库中提取尽可能少的对象。您正在将info_vouchers
表格中的每一列加载到InfoVoucher
中的各个@last_consult
类中。这是不必要的。
你可以做的一件事是@avlazarov建议的;使用#pluck
直接从数据库进入 您感兴趣的列的嵌套数组。
useful_data = InfoVoucher.where(@filters).pluck(*column_names)
您应该始终对此类任务进行排队,以便稍后由工作人员处理。 Resque和delayed_job是受欢迎的选择。
这样做的好处是用户对导出的请求将是高效的,并立即通知他们他们的请求已排队。完成后将报告通过电子邮件发送给他们。