Sylar Sylar - 1 year ago 68
Ruby Question

Ruby's .where vs. detect

I'm looking for a method that is faster and uses less server processing. In my application, I can use both



User.where(id: 1)
# User Load (0.5ms)


User.all.detect{ |u| == 1 }
# User Load (0.7ms). Sometimes increases more than .where

I understand that
returns the first item in the list for which the block returns TRUE but how does it compares with
if I have thousands of Users?

Edited for clarity.

is used in this example because I may not query for the
alone. What if I have a table column called "name"?

Answer Source

In this example

User.find_by(id: 1)

might be the fastest solutions, because they tell the database to return exactly one record with a matching id. As soon as the database found that record is returns it.

User.where(id: 1)

would return an array of objects matching the condition. In this case - since id is very likely a column with unique values - it would return an array with one instance of user.

User.all.detect { |u| == 1 }

would load all users from the database. That will result in loading thousands of users into memory, building ActiveRecord instances, iterating over that array and than throwing away all records that do not match the condition. This will be very slow compared to just loading matching records from the database.

Database management systems are optimized to run selection queries and you can improve their ability to do so by designing a useful schema and adding appropriate indexes. Every record loaded from the database will need to be translated into an instance of ActiveRecord and will consume memory - both is not for free. Therefore the rule of thumb should be: Whenever possible run queries directly in the database instead of in Ruby.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download