Ruby on Rails: Benchmarking your ActiveRecord queries

Ruby on Rails: Benchmarking your ActiveRecord queries

First of all, in some cases, the time spent in that query is really low so maybe, a good way to see if you can improve it is to compare that functionality with the same query after making some tweaks, such as lazy loading, using joins, etc.

So here is the query, I’m going to be using for benchmarking:

User.select("
count(distinct(availabilities.id)) as tot_availabilities,
count(distinct(events.id)) as tot_events,
MAX(cast(extract(epoch from availabilities.updated_at) as integer)) as last_av_updated,
users.id"
).
joins(:availability_schedules).
joins("left join events on users.id = events.doctor_id").
joins("left join availabilities on availabilities.availability_schedule_id = availability_schedules.id").
group("users.id")
Benchmark.measure do
new_results = User.select("
count(distinct(availabilities.id)) as tot_availabilities,
count(distinct(events.id)) as tot_events,
MAX(cast(extract(epoch from availabilities.updated_at) as integer)) as last_av_updated,
users.id"
).
joins(:availability_schedules).
joins("left join events on users.id = events.doctor_id").
joins("left join availabilities on availabilities.availability_schedule_id = availability_schedules.id").
group("users.id")
end

The results were

=> #<Benchmark::Tms:0x007fc8524e40b8 @cstime=0.0, @cutime=0.0, @label="", @real=0.00017499993555247784, @stime=0.0, @total=0.0, @utime=0.0>
#<Benchmark::Tms:0x007fc8532a9900 @cstime=0.0, @cutime=0.0, @label="", @real=0.00043000001460313797, @stime=0.0, @total=0.0, @utime=0.0>
=> #<Benchmark::Tms:0x007fc8381fa718 @cstime=0.0, @cutime=0.0, @label="", @real=0.00021500000730156898, @stime=0.0, @total=0.0, @utime=0.0>
=> #<Benchmark::Tms:0x007fc83628b170 @cstime=0.0, @cutime=0.0, @label="", @real=0.00032599992118775845, @stime=0.0, @total=0.0, @utime=0.0>

And about memory, I’m using these methods for that(you can copy and paste them in your terminal and then start using them):
https://github.com/heridev/memory_activerecord_into_csv_benchmark/blob/master/benchmark_helpers.rb

print_memory_usage do
print_time_spent do
another_results = User.select("
count(distinct(availabilities.id)) as tot_availabilities,
count(distinct(events.id)) as tot_events,
MAX(cast(extract(epoch from availabilities.updated_at) as integer)) as last_av_updated,
users.id"
).
joins(:availability_schedules).
joins("left join events on users.id = events.doctor_id").
joins("left join availabilities on availabilities.availability_schedule_id = availability_schedules.id").
group("users.id")
end
end

Results:

1.
Time: 0.0
Memory: 0.02 MB

2.
Time: 0.0
Memory: 0.0 MB

3.
Time: 0.0
Memory: 0.06 MB

So that’s it, you can make some tweaks to the base query and compare the results, so based on that you have a clear path on what to improve/change.
NOTE: if you didn’t notice that I’m using a different variable in the different tests I did

another_results = User.select("

I think that it is important because the assignment of those results will require a little bit of memory space and time in some cases.

Let me know if that helped you out, Cheers

H.

No Comments

Post A Comment