我的数据库中有20万个位置。所以我想将所有位置导出为CSV格式。这样做会花费太多时间下载。在Rails中优化代码的最佳方法是什么?
在控制器中:
def index
all_locations = Location.all
respond_to do |format|
format.csv { send_data all_locations.to_csv, filename: "locations-#{Date.today}.csv" }
end
end
在模型中
def self.to_csv
attributes = %w{id city address}
CSV.generate(headers: true) do |csv|
csv << ['Id', 'City', 'Address']
all.each do |location|
csv << attributes.map{ |attr| location.send(attr) }
end
end
end
答案 0 :(得分:1)
我使用自己的数据对您的代码进行了一些调整。我进行了以下更改,并使用基准测试将结果提高了7倍。
您的型号:
def self.to_csv
attributes = %w{id city address}
CSV.generate(headers: true) do |csv|
csv << ['Id', 'City', 'Address']
all.pluck(attributes).each { |data| csv << data }
end
end
使用pluck
只会获得所需的数据,然后将所有数据推入csv
数组中。
答案 1 :(得分:0)
如果您使用的是 Postgresql ,则可以在application_record.rb
def self.to_csv_copy(attrs="*", header=[])
rc = connection.raw_connection
rv = header.empty? ? [] : ["#{header.join(',')}\n"]
sql = self.all.select(attrs).to_sql
rc.copy_data("copy (#{sql}) to stdout with csv") do
# rubocop:disable AssignmentInCondition
while line = rc.get_copy_data
rv << line
end
end
rv.join
end
然后做
Location.to_csv_copy(%w{id city address}, ['Id', 'City', 'Address'])
它甚至比上述解决方案还要快。