有没有一种更有效的方法来查询 ActiveRecord 数据库以查找存在的对象,然后定义一个对象(如果存在)?

Is there a more efficient way to query ActiveRecord db for an object that exists, but then also have an object, if existing, defined?

我当前的代码如下所示

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

我想知道这里是否可以提高效率。特别是,令我印象深刻的是,有不同的方法可以针对任一 if 条件优化代码。

换句话说,如果o不存在,最好写成:

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

然而,如果 o 确实存在,它看起来更优化,因为 o.last 可以在没有另一个数据库命中的情况下被调用。请参阅上面的代码注释。

完全可以接受的答案是没有更有效的方法;我的总体来说是可以接受的。

调用 .where().last 在一次查询中仅从数据库中获取最后一条记录,这与您的 .exists? 检查非常等效(除非数据库中排序的开销比 Ruby) 所以你可以通过做这样的事情来节省一些 Ruby 内存:

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

尽管有时看起来更有效的事情在实践中可能会变得更糟。

如果您只有几封电子邮件与该呼叫相匹配,并且您的数据库在返回未排序的短列表时比返回单个已排序项目的速度更快,那么您可能会从“更差”的呼叫中受益。至少直到您调用一封在您的数据库中有数百万次点击的电子邮件,此时 Ruby 将逐渐停止以尝试将所有这些都放入内存中。

如果值得改进,您应该养成基准测试的习惯。