我有一个名为Staging
的表格,我将excel电子表格中的所有数据放入其中,通过查找现有模型/表格从中获取ID号,然后将其与当前数据库进行比较这是SQL Server 2008。
我的代码如下:
def compare
require 'rubygems'
require 'spreadsheet'
require 'set'
Spreadsheet.client_encoding = 'UTF-8'
file_full_path = File.expand_path(File.join(File.dirname(__FILE__), "../../SISlist.xls"))
book = Spreadsheet.open(file_full_path) #Select excel file
sheet = book.worksheet 0 #Select 1st worksheet
app,server,env = 0
for i in 1..500
row = sheet.row(i)
if row[0].to_s != "" # Makes sure no empty cells are saved
row.each do |t|
app = App.find_by_name(row[0].to_s)
server = Server.find_by_name(row[2].to_s)
env = Environment.find_by_code(row[3].to_s)
end
Staging.create(:app => app.id, :server => server.id, :environment => env.id)
end
end
end
我现在遇到的问题是,执行此方法需要花费很长时间(差不多20秒),而我所有其他类似方法都花费的时间不长。
任何加快这个过程的方法或者我的工作流程都是错误的,因此整个架构都是错误的?
需要帮助
答案 0 :(得分:1)
加快尝试
ActiveRecord::Base.transaction do
500.times do |i|
row = sheet.row(i)
if row[0].to_s != "" # Makes sure no empty cells are saved
app = App.find_by_name(row[0].to_s)
server = Server.find_by_name(row[2].to_s)
env = Environment.find_by_code(row[3].to_s)
Staging.create(:app => app.id, :server => server.id, :environment => env.id)
end
end
end
你也意识到app,server,env = 0
没有用零初始化所有值吗?
答案 1 :(得分:0)
如果你只有几百行,那么你可以尝试分三步:
Staging.create
来电。这样的事情:
sets = {
:apps => Set.new,
:servers => Set.new,
:environments => Set.new
}
(1 .. 500).select { |i| !sheet.row(i).to_s.empty? }.each do |i|
sets[:apps].add(row[0].to_s)
#...
end
# You could just pull in the ids and names here rather than whole objects too.
sets[:apps] = Set.where(:name => sets[:apps].to_a).each_with_object({ }) { |a,h| h[a.name] = a.id }
#...
(1 .. 500).select { |i| !sheet.row(i).to_s.empty? }.each do |i|
Staging.create(
:app => sets[:apps][row[0].to_s],
#...
)
end
基本上我猜你最大的打击是一次又一次地调用find_by...
,而不是仅仅做一次。