ActiveRecord vs SQL

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を使用するよりもはるかに高速です!



一括挿入を使用する場合( CWNVenturaに感謝):

 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:実稼働環境にランタイムを追加し、一括挿入を使用してテストする






All Articles