【发布时间】:2022-09-27 17:59:50
【问题描述】:
我有一个接受传入数据、检查错误并导入数据库的端点。传入数据最多可达 300 000 行。 Stack 是 - Ruby on Rails、Postgres、Redis、Sidekiq、干式验证。电流:
- 将数据加载到Redis;
- 准备/转换;
- 验证每一行并将其标记为有效/无效;
- 获取有效行并批量导入它们。
我需要关于如何提高此处验证步骤的性能的建议,因为有时验证大文件需要超过一天的时间。
一些细节
它基本上循环遍历后台的每一行并应用验证规则,例如
rows.each do |row|
result = validate(row)
set_status(row, result) # mark as valid/invalid
end
一些验证规则是唯一性检查——它们很重因为他们检查整个数据库的唯一性。例子:
rule(:sku, :name) do
if Product.where(sku: values[:sku]).where.not(name: values[:name]).exists?
# add error
end
end
不用说,数据库和日志在验证期间会发疯。
我尝试的另一种方法是 pluck 必要的字段来自全部数据库记录,然后循环遍历并将每一行与该数组进行比较,而不是发出数据库请求。但与庞大的阵列相比,似乎更加缓慢。
def existing_data
@existing_data ||= Product.pluck(:sku, :name, ...)
end
rule(:sku, :name) do
conflict = existing_data.find do |data|
data[0] == values[:sku] && data[1] != values[:name]
end
if conflict.present?
# add error
end
end
标签: ruby-on-rails validation import