Hi%username%!
最近、Ruby on Railsの研究を開始し、CSVファイルからMySQLテーブルにデータをインポートするタスクに直面しました。 このタスクは難しくなく、コードをかなり迅速に作成しましたが、実行中にコーヒーを注いでタバコを吸うことに驚いただけです。
-ここで何かがおかしい! 私は考えて、掘り始めました。
テスト用に、データベース内のテーブルtest_objectモデルを作成しました。
create_table:test_objects do | t | t.column:field1 ,:整数 t.column:field2 ,:整数 t.column:field3 ,:整数 t.column:field4 ,:整数 t.column:field5 ,:整数 終わり
そして小さなスクリプトを書きました:
値= [] 5000回 values.push({:field1 => rand(10000),: field2 => rand(10000),: field3 => rand(10000)、 :field4 => rand(10000),: field5 => rand(10000)}) 終わり values.each do | item | TestObject.new(アイテム).save 終わり
ランタイム:開発環境で最大 30秒、実稼働で最大22秒。 多すぎる...
それから私はar-extensionプラグインを思い出しました。これはレール上に「INSERT ... ON DUPLICATE KEY UPDATE」という形式のSQLクエリを実装するために見つけました。 単一のクエリでテーブルにデータを挿入できます。
「ar-extensions」が必要 「ar-extensions / adapters / mysql」が必要です 「ar-extensions / import / mysql」が必要です .... objs = [] values.each do | item | objs.push(TestObject.new(アイテム)) 終わり TestObject.import objs
ランタイム:開発環境で約14秒、本番環境で約12秒。 すでに優れていますが、それでもたくさんあります。
次に、このコード部分でActiveRecordの使用を放棄し、簡単なSQLクエリを使用することにしました
sql = ActiveRecord :: Base.connection() values.each do | item | sql.execute( "INSERT INTO` test_objects`(` field1`、 `field2`、` field3`、 `field4`、` field5`) VALUES( '#{item [:field1]}'、 '#{item [:field2]}'、 '#{item [:field3]}'、 '#{item [:field4]}'、 '#{item [:field5]} ') ") 終わり
ランタイム:開発環境で約5秒、実稼働で約3.5秒。
そして、トランザクションを使用する場合
sql = ActiveRecord :: Base.connection() sql.execute( "START TRANSACTION") values.each do | item | sql.execute( "INSERT INTO` test_objects`(` field1`、 `field2`、` field3`、 `field4`、` field5`) VALUES( '#{item [:field1]}'、 '#{item [:field2]}'、 '#{item [:field3]}'、 '#{item [:field4]}'、 '#{item [:field5]} ') ") 終わり sql.execute( "COMMIT")
ランタイム:開発環境では2秒、実稼働では0.8秒 ActiveRecordを使用するよりもはるかに高速です!
一括挿入を使用する場合( CWNとVenturaに感謝):
objs = [] values.each do | item | objs.push( "( '#{item [:field1]}'、 '#{item [:field2]}'、 '#{item [:field3]}'、 '#{item [:field4]}'、 '#{item [:field5]}') ") 終わり sql.execute( "INSERT INTO` test_objects`(` field1`、 `field2`、` field3`、 `field4`、` field5`)VALUES "+ objs.join( '、'))
実行時間:運用環境で〜0.1〜0.2秒!
結論: ActiveRecordは非常に便利なものであり、使用を拒否することは決してありませんが、幅広い機能が必要でなく、速度が重要なコードの部分では、通常のSQLクエリを使用することをお勧めします。
UPD:実稼働環境にランタイムを追加し、一括挿入を使用してテストする