1

データベースに「Vote」テーブルがあり、毎日サイズが大きくなり、現在は約 1 億行になっています。内部分析/洞察のために、過去数日間の毎日の投票数など、いくつかの基本的な指標を計算する rake タスクを使用していました。これは、「created_at」という日付の where 句を含む単なる COUNT です。

このレーキ タスクは、特に新しい行を挿入するときに、このインデックスを必要としない他のすべてのユーザー向けクエリのアプリ パフォーマンスに悪影響を与えたように見えるため、「created_at」のインデックスを削除するまで問題なく動作していました。 .

現在、アプリとこのテーブルで何が起こっているかについての洞察はあまりありません。ただし、自分で使用するだけであれば、このような大きなテーブルにインデックスを追加したくありません。

他に何を試すことができますか?

4

3 に答える 3

1

または、テーブルを完全に回避しVoteて、外部の集計を維持することもできます。

投票が行われるたびに、現在の投票数を保持する別の集計クラスが呼び出されます。集計レコードは 1 日 1 件になります。集計レコードには、その日に投じられた投票数を表す整数が含まれます。

集計クラスへの増分呼び出しごとに、現在の日付 (今日) の集計レコードが検索され、投票数が増分され、レコードが保存されます。レコードが存在しない場合は、レコードが作成され、それに応じて増分されます。

たとえばVoteTally、日付 (日付) と投票数 (整数) の 2 つの属性、タイムスタンプなし、関連付けなしで呼び出されるクラスがあるとします。モデルは次のようになります。

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インデックスのない 1 億レコードの句よりもはるかに高速です。この解決策では多少の不正確さが生じる可能性がありますが、毎日の投票数の逸話的な性質を考えると、それは許容できると思います。

于 2013-06-03T10:18:31.210 に答える