ActiveRecordで直接アダプタから結果を受け取る
「実践Rails」を読んでいたらP178のあたりで「これはいい!!」と思う内容が、、、しかし試してみると一番目のカラムしかとれてないよ。。。。RailsAPIドキュメントを読んでみると
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html#M001465
# File vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 26 26: def select_values(sql, name = nil) 27: result = select_rows(sql, name) 28: result.map { |v| v[0] } 29: end
わざわざ一番目の値のみ取得しています。どうしてこんなことをしているの?他所でつかってるんだろうかね?まぁ私の小さな頭ではわからんのでこいつは置いておいて、初っ端に感動したことを実現したければ「select_rows」を直接使えばいいのかなと思いちょいと書き書き
require 'rubygems' require 'activerecord' require 'pit' config = Pit.get("mysql_test", :require => { "host" => "host in mysql_test", "username" => "your username in mysql_test", "password" => "your password in mysql_test", "database" => "database in mysql_test" }) ActiveRecord::Base.establish_connection( :adapter => "mysql", :host => config['host'], :username => config['username'], :password => config['password'], :database => config['database'], :socket => "/var/lib/mysql/mysql.sock", :encoding =>"utf8") class << ActiveRecord::Base def select_rows(sql) connection.select_rows(sanitize_sql(sql)) end end query = "select id,name from contents where id > ? limit 0,3" p ActiveRecord::Base.select_rows([query,5]) #=> [["6", "hoge"], ["7", "ugo"], ["8", "nana"]]
いいね。
ちょっとベンチでも計ってみるかとquery以下を書き換える
query = "select * from contents where id > ? limit 0,100000" # ここのlimitを書き換える # warm-up ActiveRecord::Base.select_rows([query,rand(100000)]) Benchmark.bm do |job| job.report { ActiveRecord::Base.select_rows([query,rand(100000)]) } job.report { ActiveRecord::Base.find_by_sql([query,rand(100000)]) } end
ベンチ結果(三回実行)
100レコード user system total real 0.000000 0.000000 0.000000 ( 0.004188) 0.000000 0.000000 0.000000 ( 0.007171) user system total real 0.000000 0.000000 0.000000 ( 0.004254) 0.010000 0.000000 0.010000 ( 0.007426) user system total real 0.000000 0.000000 0.000000 ( 0.004416) 0.000000 0.000000 0.000000 ( 0.006560) 10000レコード user system total real 0.070000 0.020000 0.090000 ( 0.280001) 0.310000 0.050000 0.360000 ( 0.581231) user system total real 0.060000 0.020000 0.080000 ( 0.313520) 0.310000 0.050000 0.360000 ( 0.556932) user system total real 0.060000 0.020000 0.080000 ( 0.260485) 0.300000 0.050000 0.350000 ( 0.570325) 100000レコード user system total real 0.920000 0.330000 1.250000 ( 2.955603) 7.470000 0.510000 7.980000 ( 9.847504) user system total real 0.900000 0.310000 1.210000 ( 3.012176) 7.490000 0.530000 8.020000 ( 10.106686) user system total real 0.920000 0.320000 1.240000 ( 3.001611) 7.500000 0.530000 8.030000 ( 10.156798)
結果
かりかりに動かなきゃいけないバッチだけど、直接アダプタをさわりたくはない!!何とかパフォーマンスを稼げんものかなぁぁって時の選択肢として頭の片隅に置いておいてもいいと思う。