我正在从一个api中检索数据,它看起来像:
[{"type": "a", "value": 1, "identifier": 1},
{"type": "b", "value": 9, "identifier": 1},
{...},{...},
{"type": "a", "value": 2, "identifier": n}]
标识符可以是介于1-500之间的任何值,并且不能保证所有记录都具有相同的标识符。如果存在标识符,则它将具有所有相同的类型和特定的值范围。我最初用来更新记录的是这样的:
api_data.each do |x|
temp = Object.find_or_create_by_type_and_identifier_and_id(x["type]", x["identifier"], user_id)
temp.update_attributes(x)
end
这非常慢,每次加载数据时运行大约2200个查询。一旦查看数据是否存在,则一次更新,为1100个条目。当前使用的表方案如下:
create table ( type, identifier, id, value)
这是
obviously inefficient
,我只是不知道有多少。我应该尝试减少查询的数量,以便应用程序在需要更新或提取新用户数据时不会爬网?建议的一种方法是批量插入,需要更新时删除以前的条目,这样可以将其减少到2,但我不确定这是否是最好的方法。
最佳答案
如果您需要进行批量更新,则可以根据更新的性质使用ActiveRecord::Relation#update_all。
activerecord-import gem执行有效的批量插入。我不确定它是否有一个更新机制,但它对于快速插入(一个SQL语句可以容纳数千行)非常有用。只需一次快速查询~2200条记录、一些更新逻辑和一条语句就可以插入丢失的记录。
一个适度更极端但可能更快的解决方案可能是加载数据库中的每个记录、协调新状态、删除所有要删除或更改的行(快速批量操作),以及使用activerecord导入批量插入新的/修改的行。这将是最多三个数据库操作,将运行非常快,约2200条记录,但不够快,你想做的每一个变化。
最后,您可以使用SQL。看起来您的更改已经足够基本了,您只需执行YourModel.connection.execute "UPDATE some_things SET foo = 'whatever'"
。不过,我怀疑你想做什么就做什么是有障碍的。查看ActiveRecord文档。有许多批量操作,如delete_all
,update_all
,等等。