【问题标题】:Efficent way to select belongs_to model from another Model, in Rails 5?在Rails 5中从另一个模型中选择belongs_to模型的有效方法?
【发布时间】:2019-12-09 16:19:56
【问题描述】:

我有 2 个模型:

Contact -> has_many :messages 

Message -> belongs_to :contact

我想从我的消息表中选择最后 10 个联系人(作为对象数组,而不仅仅是 id)

这是我的尝试(效果很好):

Contact.where(id: Message.pluck(:contact_id).uniq.last(10))

但是还有其他更好的方法吗?

编辑 我想从我的消息表中选择最后 10 个联系人

【问题讨论】:

  • 什么是“最后 10 个联系人”?除非您没有向我们展示其他代码,例如 default_scope,否则您的代码本质上只是获取“10 个有消息的随机联系人”。
  • 抱歉,我想从我的消息表中选择最后 10 个联系人
  • @spickermann 我想加载最近收到消息的10个联系人(通过消息的created_at)

标签: ruby-on-rails ruby activerecord ruby-on-rails-5


【解决方案1】:

我会在一个数据库查询中执行此操作。

Contact
  .distinct
  .joins(:messages)
  .order('messages.created_at DESC')
  .limit(10)

【讨论】:

  • 我一直有这样的疑问:在某些时候,进行两个查询是否比连接更好?或者,在某些情况下,可能是内部查询而不是联接?我并不是要怀疑这个答案。我相信这是一个完美的问题。但我希望你能消除这个疑问。
  • 这真的取决于您的数据库架构、表大小和索引。我的经验法则是,一个查询大多数时候比两个查询快。但你是对的:当两个表都很大并且有数百万行时,加入它们可能是个坏主意。但只要 OP 对 Message.pluck(:contact_id).uniq.last(10) 满意(将所有 ids 记录加载到内存中,然后运行秒查询),IMO 就可以安全地假设 OP 正在处理的表对于 JOIN 解决方案来说足够小。
  • 是的,当然。这只是一个附加问题,与当前问题并不特别相关。感谢您清除它。
  • 抱歉我的英语不好@spickermann,对你来说,JOIN 更适合大桌子吗?在我的情况下,我必须选择在 db 中生成消息的最后 10 个或 15 个联系人(也就是说,从最后的消息中)而不重复联系人(uniq)
  • 你说的不工作是什么意思?是否有意外结果或错误消息?
【解决方案2】:

您可以尝试以下查询:

Contact.where(id: Message.distinct.order(created_at: :desc).limit(10).select(:id))

这将产生以下 SQL:

"SELECT  DISTINCT \"messages\".\"id\" FROM \"messages\"   ORDER BY \"messages\".\"created_at\" DESC LIMIT 10"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    相关资源
    最近更新 更多