Reputation: 1905
I expect this call
Model.maximum(:updated_at)
to be faster than this one
Model.order(:updated_at).last.updated_at
Is anyone able to confirm this assertion? and, if true, explain why?
Upvotes: 12
Views: 7589
Reputation: 27779
You can use the the Benchmark module to investigate easily, e.g.:
require 'benchmark'
n = 50000
Benchmark.bm do |x|
x.report('maximum') { n.times.do; v1; end }
x.report('order-pluck') { n.times do; v2; end }
end
def v1
clear_cache
Model.maximum(:updated_at)
end
def v2
clear_cache
Model.order(:updated_at).pluck(:updated_at).last
end
def clear_cache
ActiveRecord::Base.connection.query_cache.clear
end
To make it worth doing this with n > 1 you'll have to clear the various caches that might be involved. There may well be a cache in your db server, separate from the ActiveRecord cache. For instance to clear the Mysql cache you could call:
`mysql mydb -e 'RESET QUERY CACHE'`
Upvotes: 6
Reputation: 4005
Your expectation is correct.
When you call Model.maximum(:updated_at)
, you ask your DB to return just a single value.
When you call Model.order(:updated_at).pluck(:updated_at).last
, your database returns you all the values for the updated_at
column in the table, which consumes more memory (because you have to build a big array), and takes more time.
Upvotes: 1