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

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

最近用 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

这个时候我一般推荐改用 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 这种需求,我第一个想到的就是用存储过程

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