2009-05-28 2 views
1

これを最適化されたパフォーマンスのためにモデル化する最良の方法は何かについては興味があります。時間データの整合性多対1の関係の集計データをモデル化する効率的な方法(例えば、stackoverflow質問の投票数)

は、私は質問が多くの票多くのクエリのために

しかし、我々は例えばに(投票の総数を有する唯一の心配してい

Question 
    id 
    title 
Votes 
    id 
    user 
    question 

stackoverflowの例を続けます質問の横に表示)。

良好なリレーショナルDB理論は、2つのエンティティ(QとV)を別々のリレーションとして作成し、結合を要求して合計または集計コールを要求します。

もう1つの可能性は、通常のフォームを破棄し、投票の集計値を質問(例:Question.votes)の属性として具体化することです。パフォーマンスは読まれますが、あなたの「投票」データを得ることができなくなった場合、その質問レコードにはもっと多くの権利が必要となり、結果としてパフォーマンスが低下します。

キャッシングなどを含む他の手法を使用できます。しかし、私はちょうど最高のソリューションは何がパフォーマンス賢明なのだろうか?サイトのトラフィックが高く、質問よりもかなり多くの票を受け取ったとします。

非リレーショナルモデルにもオープンです。

答えて

1

この場合、特にVotesテーブルの(質問)にインデックスがある場合、結合が遅すぎることはほとんどありません。それは本当にあまりにも遅い場合

、あなたは質問表内の投票数をキャッシュすることができます

id - title - votecount 

あなたが投票を記録するたびにvotecountを更新することができます。たとえば、ストアドプロシージャから、またはアプリケーションコードから直接呼び出します。

これらの更新は難しいですが、一貫性について心配しているわけではないので、投票が正確ではない場合もあります。 1を返します

UPDATE q 
SET votecount = count(v.question) 
FROM questions q 
LEFT JOIN votes v on v.question = q.id 

集計数(v.question)(*)カウントとは反対に何の疑問が、見つからなかった場合は0を返し、:すべてのエラーを修正するには、定期的にのような、すべてのキャッシュされたカウントを再生することができます。

ロックは問題がある場合は、別の方法としてバイパスロック(再び、データの整合性は低い優先度であることに基づく。)

に「コミットされていない読んで設定したトランザクション分離レベル」または「(NOLOCK)で」使用することを検討してください「読み取りコミットされたスナップショット」を検討してください。これは、読み込み量が多く、書き込みアクティビティが少ないデータベースのためのものです。

ALTER DATABASE YourDb SET READ_COMMITTED_SNAPSHOT ON; 

これはSQL Server 2005以降で使用できます。これはOracleがデフォルトでどのように動作するかであり、stackoverflow自体が使用するものです。それについてもcoding horror blog entryがあります。

+0

私は質問の投票数の提案を具体化することに取り組んだ。私は別の方法がある場合、これは2倍の書き込み(任意の読み取りをロックアウト)が原因であると思っていた 私は適切なインデックスで知っている。しかし、私が多くの質問を取得していて、多分多くの関係(例:投票数とコメント数)がある場合、結合は厄介になります – nategood

+0

投稿が編集されました。早すぎる最適化をしていないことに注意してください。私が通常の結合から離れる前に、パフォーマンス問題の数に裏打ちされたハードな証拠がなければなりません。 – Andomar

1

私はソーシャルネットワーキングサイトでこのようなことを行うためにSQL 2005のインデックス付きビューを使用しました。私たちの負荷は確かに読み込み/書き込みの割合が高いので、うまくいきました。

+0

私はhainstechに同意します。 Votes Tableの索引付きビューを作成し、それを質問とカウントで集計します。 – Jeff

0

私は、アプリケーションの有効期間中投票をメモリに保持することをお勧めします。 なぜアイテムを一度ロードして、リクエストに基づいて最初の金額が何だったのかを尋ねるときに、カウントと同じような単純なものでデータベースにヒットするのはなぜですか。 これはまた、リポジトリの実装方法と多くの関係があります。質問オブジェクトが票を積んだり、投票数を積み重ねると、プロセスを高速化してメモリに保存しておくことは問題ありません。依然として票をデータベースに残しておき、申請書の数をそのまま維持してください。

関連する問題