2013-03-19 36 views
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,但我不确定这是否是最好的方法。

+0

做一个批量插入到临时表并从中更新主表。 – 2013-03-19 19:40:16

+0

或使用线程加速 – phoet 2013-03-19 19:40:45

回答

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等。

+0

更新全部基本上在做WHERE x = y,在这种情况下,由于数据是异构的,所以这不起作用。我正在更深入地看到上面评论中提到的分段思路,但是现在我正在使用connection.execute来解决这个问题。我希望能有更多'rails'-esc的答案,但这就是我目前所做的。 – Sturm 2013-03-19 20:20:05