2

我正在从如下所示的 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,但我不确定这是否是最好的方法。

4

1 回答 1

1

如果您需要进行批量更新,您可能能够摆脱ActiveRecord::Relation#update_all,具体取决于更新的性质。

activerecord-import gem执行高效的批量插入。我不确定它是否有更新机制,但它非常适合快速插入(一条 SQL 语句用于数千行)。只需快速查询约 2200 条记录、一些更新逻辑和插入缺失记录的单个语句。

一个更极端但可能更快的解决方案可能是加载数据库中的每条记录,协调新状态,删除所有要删除或更改的行(快速批量操作),并使用 activerecord 批量插入新/修改的行-进口。这将是最多三个数据库操作,并且会非常快速地运行约 2200 条记录,但速度不够快,以至于您希望在每次更改时都执行此操作。

最后,您可以求助于 SQL。看起来你的改变是基本的,你可以简单地做YourModel.connection.execute "UPDATE some_things SET foo = 'whatever'"。不过,我怀疑有一种 Railsy 方法可以做任何你想做的事情。查看ActiveRecord文档。有许多批量操作,如delete_all,update_all等。

于 2013-03-19T20:16:43.717 回答