Let’s take some time to get familiar with
select. They’re two very useful methods in ActiveRecord and using both effectively can really contribute to improving performance of your app.
Before there was
pluck there was
select was THE WAY for you to query for a single field from your database.
1 2 3 4
In this example,
select creates an array of
User models where only
id is returned. (You need to include
to_a so that the query runs, without it you’ll simply get an
pluck was a introduced in Rails 3.2 and with it you can perform a
select and skip the overhead of building ActiveRecord models.
1 2 3 4
The results are nearly the same from an iteration standpoint. With
pluck your results are an
Array of integers, instead of
User models. Now I can hear you saying: “Wait just a minute there! Both queries took 0.9ms, so there’s no difference between the two methods”. And to that I would reply…
The difference is in the cost of object construction, which Rails is hiding from you!
Let’s use Benchmark to find out the real cost of
pluck. For each method we’ll do 5 runs, reject the lowest and highest times, then average the 3 results.
1 2 3
1 2 3
I ran the two queries across 10,000 user records, and it’s easy to see that select was 91% slower than pluck. For the record, both queries take the same amount of time to run, it’s the object creation that eats up that additional time with
This is no big secret.
pluck was introduced to remove the overhead caused by Rails object creation, which was commonly seen when running a query like this:
Something I didn’t know prior to writing this post is that you can
pluck on multiple columns! (Note: that this is available as of Rails 4.0)
1 2 3
pluck is however slightly different than
select when it comes to multiple columns. With select you can pass
:first_name, :last_name, :email or
[:first_name, :last_name, :email] whereas if you pass an array to pluck it’s going to barf on you – oddly, this was a deliberate choice.
This post wouldn’t be complete without talking about the use case for
select. Namely when you need to run model methods on the results that come back from
select. There’s no way to do that with
pluck. In one simple sentence:
pluck for model values, select for model objects
That’s it for now. In the future you can look forward to regular posts on difference ways to improve the performance of your Rails application!