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

lrbnew · February 11, 2014 · Last by anisko replied at March 09, 2026 · 9863 hits

最近用 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 这种需求,我第一个想到的就是用存储过程

The player quickly learns that the environment is dynamic and can react and explode. moto x3m

You need to Sign in before reply, if you don't have an account, please Sign up first.