【问题标题】:Is there a more efficient way to fetch this array?有没有更有效的方法来获取这个数组?
【发布时间】:2015-04-26 20:52:17
【问题描述】:

我有一个模型项目,用户可以通过创建新的 UpVote 或 DownVote 对其进行投票。创建 UpVote 或 Downvote 时,它​​会记录用户的 ip 地址和 Item 的 id。我想列出当前用户的ip没有投票的前100个Item的数组。

到目前为止,这是我所拥有的:

架构

create_table "up_votes", force: true do |t|
  t.string   "ip"
end

create_table "down_votes", force: true do |t|
  t.string   "ip"
end

型号

class Item < ActiveRecord::Base

  def up_votes_array
    self.up_votes.map(&:ip).to_a
  end

  def down_votes_array
    self.down_votes.map(&:ip).to_a
  end

  def up_voted?(ip)
    self.up_votes_array.include? ip
  end

  def down_voted?(ip)
    self.down_votes_array.include? ip
  end

控制器

@not_voted = Item.where(show: true).select { |item| !item.up_voted?(request.remote_ip) }.select { |thing| !item.down_voted?(request.remote_ip) }.sort_by(&:alphabetical).reverse.first(100).shuffle

它可以工作,但有些东西似乎不必要地复杂,我担心随着数据库的增长,它可能会变得低效。有没有更有效的方法来获取这个数组?

我正在使用 Rails 4 和 Sqlite3。

【问题讨论】:

  • 这里的Thing 是什么。它和Item有什么关系?
  • 糟糕,对不起,我把它和我的另一张桌子混在一起了。应该是Item

标签: sql ruby-on-rails ruby performance sqlite


【解决方案1】:

我认为理想的查询应该是这样的:

Item.where(show: true).joins(:up_votes).joins(:down_votes).where('up_votes.ip != ?', request.remote_ip).where('down_votes.ip != ?', request.remote_ip).limit(100)

这将产生一个最佳查询并在您的内存中加载 100 行,这与给定的查询相反,它为Item 加载整个表,并且所有迭代都在它的赞成票和反对票上进行检查。

您也可以将查询组合在一起: Item.where(show: true).joins(:up_votes).joins(:down_votes).where('up_votes.ip != ? and down_votes.ip != ', request.remote_ip, request.remote_ip).limit(100)

【讨论】:

  • 这行得通吗?如果一个项目有来自会话 ip 和其他一些 ip 的 up_vote 怎么办?它至少有一个 up_vote 是 != ip 所以它会在不应该的时候被选中。
  • 如果它的任何赞成或反对票有 request.remote_ip,它不会选择该项目,即使 项目的其他赞成或反对票有一些 ip。它应该返回如下查询:select * from items inner join up_votes on items.id = up_votes.item_id inner join down_votes on items.id = down_votes.item_id where up_votes.ip &lt;&gt; "127.0.0.1" and down_votes.ip &lt;&gt; "127.0.0.1" limit 3。试一试。
  • 酷。一直是教育,在这里闲逛。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多