読者です 読者をやめる 読者になる 読者になる

Railsで簡単バルクインサート

SQLには複数のデータを以下のようにぼぼぼっと登録する機能があります。

INSERT INTO books (columns) VALUES (values), (values), (values);

これはバルクインサートと呼ばれて、普通に3回違うデータをINSERTするよりパフォーマンスがよくなります。

場合によっては10倍以上速くなるときもある(というかデータが大くなればなるほどその差も大きくなるかな)くらいとのこと。

バルクインサートが速い理由に関しては、

バルクインサートが早い理由は一括でインサートするから。通常のインサートをループするとI/Oがループの回数分発生してしまう。 しかし、一括でインサートする場合だとI/Oが少ない為、MySQLの処理が早いと思われる。

via: http://nikuniku.me/?p=306

トランザクションを発行→何回もインサート処理をループさせるよりもコンテキストスイッチの回数が減りますからね。

via: http://nasunoblog.blogspot.jp/2012/05/sql-server_10.html

インサート処理を束ねたトランザクションを発行することでアプリケーション側からDB側へのリクエスト回数を減るという認識で大丈夫だろうか。

Railsでは

Rails標準のO/RマッパーであるActiveRecordでは、activerecord-importを使います。

https://github.com/zdennis/activerecord-import

  • ActiveRecord複数レコード、BULK INSERTする方法とパフォーマンスについて

http://qiita.com/xend/items/79184ded56158ea1b97a

こいつを使うことによって、

cloths = []
cloths << Cloth.new(title: "ブラジル")
cloths << Cloth.new(title: "ケニア")
cloths << Cloth.new(title: "ルワンダ")
Cloth.import cloths

みたいな感じでバルクインサートでSQLを発行することができます。

配列を突っ込めばいいってのは簡単だしクール!