1

我的数据库中有一个“投票”表,它的大小每天都在增长,目前大约有 1 亿行。对于内部分析/洞察,我曾经有一个 rake 任务,它会计算一些基本指标,比如过去几天每天的投票数。它只是一个在“created_at”日期带有 where 子句的 COUNT。

这个 rake 任务运行良好,直到我删除了“created_at”上的索引,因为它似乎对所有其他不需要此索引的面向用户的查询的应用程序性能产生了负面影响,尤其是在插入新行时.

目前,我对我的应用程序和此表中发生的事情没有太多见解。但是,如果只是为了我自己的使用,我真的不想在这么大的表上添加索引。

我还能尝试什么?

4

3 回答 3

1

或者,您可以完全避开Vote表格并保留外部计数。

每次投票时,都会调用一个单独的计数类来保持对投票的持续计数。每天将有一个计数记录。计票记录将有一个整数表示当天的投票数。

对计数类的每次增量调用都会找到当前日期(今天)的计数记录,增加投票计数并保存记录。如果不存在记录,则会创建一个记录并相应地递增。

例如,让我们VoteTally使用两个属性调用一个类:日期(日期)和投票计数(整数),没有时间戳,没有关联。这是模型的样子:

class VoteTally < ActiveRecord::Base

  def self.tally_up!
    find_or_create_by_date(Date.today).increment!(:votes)
  end

  def self.tally_down!
    find_or_create_by_date(Date.today).decrement!(:votes)
  end

  def self.votes_on(date)
    find_by_date(date).votes
  end

end

然后,在Vote模型中:

class Vote < ActiveRecord::Base
  after_create :tally_up
  after_destroy :tally_down

  # ...

  private

  def tally_up ; VoteTally.tally_up! ; end
  def tally_down ; VoteTally.tally_down! ; end

end

这些方法将获得投票计数:

VoteTally.votes_on Date.today
VoteTally.votes_on Date.yesterday
VoteTally.votes_on 3.days.ago
VoteTally.votes_on Date.parse("5/28/13")

当然,这是一个简单的示例,您必须对其进行调整以适应。这将导致在投票期间进行额外的查询,但它比where没有索引的 100M 记录上的子句快得多。此解决方案可能会出现轻微的错误,但我认为鉴于每日计票的轶事性质,这是可以接受的。

于 2013-06-03T10:18:31.210 回答
0

它只是一个在“created_at”日期带有 where 子句的 COUNT。

在这种情况下,您可以使用的唯一可靠索引是created_at...

如果写入性能是一个问题(我认为这不太可能......)并且您正在使用复合主键,那么使用该索引对表进行聚类也可能会有所帮助。

于 2013-06-03T09:34:49.013 回答
0

如果索引确实对写入性能有影响,并且只是偶尔运行统计数据的少数人,您可以考虑另一种通用方法:

您可以将“事务处理数据库”与“报告数据库”分开。

您可以定期更新您的报告数据库,并仅在那里创建仅报告索引。更重要的是,关于报告的查询不会与面向事务的流量发生冲突,而且它们运行多长时间并不重要。

当然,这增加了一定的延迟,也增加了系统的复杂度。另一方面,如果您定期前滚您的报告数据库,您可以确保您的备份方案确实有效。

于 2013-06-03T10:28:43.203 回答