我从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,但我不确定这是否是最好的方法。
答案 0 :(得分:1)
如果您需要进行批量更新,您可以使用ActiveRecord::Relation#update_all,具体取决于更新的性质。
activerecord-import gem执行有效的批量插入。我不确定它是否有更新机制,但它很适合快速插入(数千行的单个SQL语句)。它只需要对~2200条记录进行一次快速查询,一些更新逻辑,以及一条插入缺失记录的语句。
适度更极端但可能更快的解决方案可能是加载数据库中的每条记录,协调新状态,删除要删除或更改的所有行(快速批量操作),以及批量插入新的/修改的行使用activerecord-import。这最多只能进行三次数据库操作,并且可以非常快速地运行~2200条记录,但速度不够快,以至于您不希望在每次更改时都这样做。
最后,您可以使用SQL。您的更改看起来很基本,只需执行YourModel.connection.execute "UPDATE some_things SET foo = 'whatever'"
即可。我怀疑有一种Railsy方式可以做任何你想做的事情。查看ActiveRecord文档。有许多批量操作,例如delete_all
,update_all
等。