0

我的应用程序中有一些遗留代码,用于将模型的所有表行与供应商 API 调用的结果进行比较。

这一直很好,直到上周表格行数和供应商的结果数量都大幅增加。

表基数从 1,657 变为 59,699,API 返回的结果数约为 150,000。

代码所做的是查看 API 结果以检查是否未找到当前表行数据,如果是,则当前数据在数据库中是孤立的,因为它存在于数据库中,但不在供应商给我们的数据中。

查看 150,000 个结果以检查是否存在某些东西对我来说听起来并不特别聪明,而且看起来就是这种情况,因为我什至不知道这需要多长时间才能运行,因为视图仍在加载大约小时 :/

控制器

@telco_numbers = TelcoNumber.orphaned_in_db

模型

def self.orphaned_in_db
  db_numbers = self.find(:all)
  listed_numbers = self.all_telco
  orphaned_numbers = []
  db_numbers.each do |db|
    scan = listed_numbers.select{ |l| l.number == db.number}
    orphaned_numbers.push(db) if scan.empty?
  end
  return orphaned_numbers
end

def self.some_telco(per_page, page = 1)
  page = 1 if page.nil?
  # this is the first api call which returns a link which is then used for the next api call
  api_call = TelcoApiv3.new("post", "/numbers/#{TelcoApiv3.account_id}/allocated/all")
  listed_numbers = TelcoApiv3.poll(api_call.response["link"])
  return listed_numbers.collect do |ln| 
    ln.store("countrycode", ln["country_code"])
    TelcoNumber.new ln
  end
end

def self.all_telco(page = 1)
  listed_numbers = some_telco(@@max_nlist_results, page)
  if listed_numbers.length == @@max_nlist_results
    return listed_numbers.concat(all_telco(page + 1))
  else
    return listed_numbers
  end
end

示例 API 结果格式:

[{"country_code":"44","number":"1133508889"},....

与模型表中numbernumber列相关。(它存储为 varchar 而不是数字)。

另外,api结果是按数字升序返回的,所以已经排序了,所以我认为这会让事情变得更好?

4

1 回答 1

1

你为什么不尝试阵列差异。首先制作两个 db_numbers &listed_numbers 数组,然后从较大的数组中减去较小的数组,如下所示:

def self.orphaned_in_db
  db_numbers = self.find(:all).map{|x| x.number}
  listed_numbers = self.all_telco.map{|x| x.number}
  orphaned_numbers = db_numbers - listed_numbers
  orphaned_results = self.find(orphaned_numbers)
  return orphaned_results
end

当我从 db_numbers 中减去listed_numbers 时,我将得到不匹配的结果集。现在您可以根据数据库中的 orphaned_numbers 找到结果。它会快得多。谢谢

于 2013-11-11T11:12:47.830 回答