Ruby ActiveRecord 批量插入数据的性能问题

lrbnew · 2014年02月11日 · 最后由 hooopo 回复于 2014年06月06日 · 6 次阅读

最近用padrino作点东西,开发环境下批量插入数据,特别慢,1000条记录大概1分钟。 查看debug信息,发现1000条insert后面,带了1000个commit;

原因很明显,冗余commit带来的性能下降,所以,如果能实现多次insert,一次commit,应该能解决。

自己是ruby新手,也没找到个解决办法,直到看见这个贴http://ruby-china.org/topics/580 里面@yangyanhao 推荐的资料https://www.coffeepowered.net/2009/01/23/mass-inserting-data-in-rails-without-killing-your-performance/

这个完美的解决了我的问题,从原来的1分钟入库,变成1秒钟入库! debug日志变成了1000个insert后面带一个commit。

附修改前入库代码 CodeName.create @carry

修改后入库代码 ActiveRecord::Base.transaction do CodeName.create @carry end

共收到 15 条回复

这个时候我一般推荐改用sequel http://sequel.rubyforge.org

sequel提供了import方法 http://sequel.jeremyevans.net/rdoc/classes/Sequel/Dataset.html#method-i-import DB[:table].import([:x, :y], [[1, 2], [3, 4]])

INSERT INTO table (x, y) VALUES (1, 2)

INSERT INTO table (x, y) VALUES (3, 4)

@nouse 看到这一句话,有一种想去研究的冲动

"Sequel has restored my faith in Ruby. It's really amazing. The O/RM I've been hoping for for years." -- Sam Smoot, creator of DataMapper

谢谢推荐

Sequel 可以单独做 migrations 操作不依赖任何环境哦

#3楼 @martin 顶ActiveRecord-Import, 我碰到大量插入是也用的这个,

最近也在做类似这样的东西,重点是批量插入的时候,要避免 Model 的 validation 和 callback,我现在都是用 sanitize_sql 来手工拼接 SQL ,执行,unique 的验证通过数据库唯一索引来搞

Insert 语句可以直接容错已有记录的情况,比如:

INSERT INTO photos (user_id, file_id, lat, lng, created_at, updated_at, deleted_at) VALUES (27,'dbcb70427c4e6292d3462ca1dc65bf02d505f515',0.0,0.0,'2014-02-27 06:25:45','2014-02-27 06:25:45',null) ON DUPLICATE KEY UPDATE updated_at = values(updated_at), deleted_at = values(deleted_at)

#8楼 @huacnlee 我记得做过一个批量导入,手工拼1000条sql,然后commit一次。这样确实快不少啊!

我最近还通过 Http Api 往服务器里塞数据,服务器也是我们自己维护的 大概一秒只能塞 0.5 条数据,塞了 3W 多条数据,花了 4 个多小时……

#10楼 @wuwx 3W 条 4 小时…

事物么?

#8楼 @huacnlee mysql这种需求,我第一个想到的就是用存储过程

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册