Home > database >  Is there a more efficient way to query ActiveRecord db for an object that exists, but then also have
Is there a more efficient way to query ActiveRecord db for an object that exists, but then also have

Time:03-08

My current code looks like this

o = Order.where(email:"email")
if o.present?
  do_something_with(o.last)
else
  return "Message"
end

I'm wondering if there are more efficiency gains to be had here. Particularly, it strikes me that there are different ways to optimize code for either of the if conditions.

In other words, if o does NOT exist, it would be better to have written:

if Order.where(email:"email").exists?
  # do_something_with(o.last) wouldn't work, you'd need to write
  # o = Order.where(email:"email").last
  # which requires another db call and is thus not efficient IF O WERE existing
else
  return "Message"
end

However if o does exist, it seems more optimal as is, since o.last can be called without another db hit. See code comments above.

Totally acceptable answer that there is not a more efficient way of doing this; what I have is generally acceptable.

CodePudding user response:

Calling .where().last fetches only the last record from the database in one query, which is pretty equivalent to your .exists? check (unless the overhead of sorting in the db is worse than in Ruby) so you can save some Ruby memory by doing something like this:

o = Order.where(email: "email").last
if o
  do_something_with(o)
else
  return "Message"
end

Although sometimes things that seem more efficient could turn out to be worse in practice.

If you only have a few emails that match that call, and your database is faster at returning a short list with no sorting than it is for a single item sorted, you might benefit from the "worse" call. At least until you call for an email that has millions of hits in your database, at which point Ruby will grind to a halt trying to fit all that in memory.

If it's worth improving, you should get in the habit of benchmarking.

  • Related