我们正在尝试生成CSV文件供用户下载。但是,它非常慢,10k行CSV大约需要5分钟。
改善任何好主意?代码如下:
def download_data
start_date, end_date = get_start_end_date
report_lines = @report.report_lines.where("report_time between (?) and (?)", start_date, end_date)
csv_string = CSV.generate do |csv|
report_lines.each do |report_data|
csv << [report_data.time, report_data.name, report_data.value]
end
end
respond_to do |format|
format.csv { send_data(csv_string, :filename => "#{Time.now}.csv", :type => "text/csv") }
end
end
答案 0 :(得分:3)
我首先要检查report_time
是否已编入索引,未编入索引report_time
肯定会导致缓慢。有关添加索引的详细信息,请参阅Active Record Migration
。
其次,您可以将结果减少到您需要的范围,即不选择所有列,而只选择time
,name
和value
:
report_lines = @report.report_lines
.where("report_time between (?) and (?)", start_date, end_date)
.select('time, name, value')
尝试:
def download_data
start_date, end_date = get_start_end_date
report_lines = @report.report_lines.where("report_time between (?) and (?)", start_date, end_date).select('time, name, value')
csv_string = CSV.generate do |csv|
report_lines.map { |row| csv << row }
end
respond_to do |format|
format.csv { send_data(csv_string, :filename => "#{Time.now}.csv", :type => "text/csv") }
end
end
答案 1 :(得分:1)
检查哪个部分需要花费这么多时间。
如果是SQL查询,那么尝试优化它:检查你是否有索引,也许你需要强制另一个索引。
如果查询速度很快,但Ruby很慢,那么你可以尝试两件事:
fastest-csv
)ActiveRecord
个对象,而是为每一行提取连接的字符串。如果它更好,但仍然太慢,你最终只能在数据库中生成一个大字符串并只为它呈现它(这个解决方案可能看起来不太好看,而且看起来很难看,但在一个项目中我不得不使用它,因为这是最快的方式)