CSVエクスポートはmysqlに任せた方が1000倍早い

CSVでエクスポートさせるときFasterCSVはよく使うけど、レコード数が増えればそれに比例して処理スピードが鈍化する。

 People.find(1, :include=>:profiles)

としたとき、もしhas_manyしているprofileが1000個あった場合、そもそもオブジェクトのnewがボトルネックになる。これをさらにFasterCSVでeach回してcsv化するとなるとさらに遅い。1000ならまだいけるが、1万、10万というオーダーになると終わる。

なので、こういうときはmysqlがバックアップ用としてサポートしているsqlを使う。直接mysqlsqlを投げてcsvを吐いてもらおう。

 Profile.connection.execute("SELECT id, name, created_at from profiles where people_id = 1 INTO OUTFILE 'test.csv'
 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"';") 

ベンチマークは詳しく取ってないけど、レコードが数万行あったとしても、数秒でエクスポートが完了する。SELECTで少し複雑なことも可能。