Ruby on rails 极慢的csv导出
我们正在尝试生成一个CSV文件供用户下载。然而,它的速度非常慢,对于10k行CSV,大约需要5分钟 有改进的好主意吗?代码如下:Ruby on rails 极慢的csv导出,ruby-on-rails,ruby,csv,Ruby On Rails,Ruby,Csv,我们正在尝试生成一个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.ge
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
def下载数据
开始日期,结束日期=获取开始日期
报告行=@report.report行。其中(“报告时间介于(?)和(?)之间”,开始日期,结束日期)
csv_string=csv.generate do|csv|
报告行。每个行都报告数据|
csv“#{Time.now}.csv”,:type=>“text/csv”)}
结束
结束
我会首先检查报告时间
是否已编制索引,未编制索引的报告时间
肯定会导致速度缓慢。有关添加索引的详细信息,请参阅
第二,您可以将结果缩减到您需要的范围,即不选择所有列,而只选择时间
、名称
、和值
:
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
def下载数据
开始日期,结束日期=获取开始日期
报告行=@report.report行。其中(“报告时间在(?)和(?)之间)”,开始日期,结束日期。选择('time,name,value'))
csv_string=csv.generate do|csv|
report_lines.map{| row | csv“{Time.now}.csv”,type=>“text/csv”)}
结束
结束
我会首先检查报告时间
是否已编制索引,未编制索引的报告时间
肯定会导致速度缓慢。有关添加索引的详细信息,请参阅
第二,您可以将结果缩减到您需要的范围,即不选择所有列,而只选择时间
、名称
、和值
:
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
def下载数据
开始日期,结束日期=获取开始日期
报告行=@report.report行。其中(“报告时间在(?)和(?)之间)”,开始日期,结束日期。选择('time,name,value'))
csv_string=csv.generate do|csv|
report_lines.map{| row | csv“{Time.now}.csv”,type=>“text/csv”)}
结束
结束
检查哪个部分花费了这么多时间
如果是SQL查询,那么尝试优化它:检查是否有索引,可能需要强制另一个索引
如果查询速度快,但Ruby速度慢,那么您可以尝试两种方法:
- 或者尝试一些更快的CSV库(如
)最快的CSV
- 在SQL中生成尽可能多的CSV。我的意思是:不是在那里创建
对象,而是为每一行获取连接的字符串。如果更好,但仍然太慢,您可以在数据库中只生成一个大字符串,然后为ust渲染它(此解决方案可能看起来不太好,而且看起来很难看,但在一个项目中我不得不使用它,因为它是最快的方法)ActiveRecord
- 或者尝试一些更快的CSV库(如
)最快的CSV
- 在SQL中生成尽可能多的CSV。我的意思是:不是在那里创建
对象,而是为每一行获取连接的字符串。如果更好,但仍然太慢,您可以在数据库中只生成一个大字符串,然后为ust渲染它(此解决方案可能看起来不太好,而且看起来很难看,但在一个项目中我不得不使用它,因为它是最快的方法)ActiveRecord
get\u start\u end\u date
和report\u line
很难说是什么让代码变慢了。如果看不到get\u start\u end\u date
和report\u line
很难说是什么让代码变慢了。