Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Faster way to find the last updated timestamp

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?

like image 896
Nanego Avatar asked Jul 27 '15 15:07

Nanego


2 Answers

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.

like image 154
Yury Lebedev Avatar answered Nov 03 '22 23:11

Yury Lebedev


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'`
like image 23
Mori Avatar answered Nov 04 '22 00:11

Mori