Ruby on rails 通过在RubyonRails中搜索加快查找速度
我有一个名为Ruby on rails 通过在RubyonRails中搜索加快查找速度,ruby-on-rails,ruby,performance,ruby-on-rails-3,sql-server-2008,Ruby On Rails,Ruby,Performance,Ruby On Rails 3,Sql Server 2008,我有一个名为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
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秒),而我所有其他类似的方法都不需要那么长时间
有没有加快这个过程的方法或者我的工作流程是不正确的,因此整个架构是错误的
需要帮助以加快尝试
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
不会将所有值初始化为零?如果您只有几百行,则可以尝试分三步执行:
暂存。创建调用
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\u by…
,而不是只调用一次。你可以使用@jaydel,这对RoR 3有用吗?因为上面写着2.3,所以可能会贬值?是的,看起来是这样。对不起,链接不正确。这里有一个更好的——非常感谢@jaydel,我一定会看看它的。你这么做是为了什么<代码>行。每个都做| t |?哦?我以为它会初始化它们?否则我可以声明它们的存在而不初始化它们吗?我尝试了你的代码,但是我得到了一条错误消息调用了nil的id,它会被错误地设置为4——如果你真的想要nil的id,请使用object\u id
。知道为什么吗?我设法让它工作了,但出现的错误是由于500.times do | I |
循环造成的,但不知道为什么。不幸的是,使用事务并没有提高它的速度。还有其他想法吗?我错过了一个端点检查它应该做同样的事情。我几小时后回来,我会努力加快执行速度。你真是个天才,问题在于if
语句。使用除非第[0]行为空?
将速度至少提高一半。但如果性能可以进一步提高,那将是非常棒的。另外,500.times do
不起作用,总是会产生错误,因此我在1..500中使用了for I
注意:这个版本不做行。each--我真的认为在原始版本中,您是在为每一行读取每一列。