ユーザー「投票」テーブルと「ユーザー」テーブルを持つデータベースがあります。データベースは短時間でかなり大きくなると思うので、最も効率的な方法を使用したいと思います。
毎回「votes」テーブルから WHERE ステートメントを使用して投票数を COUNT() するか、「user」テーブルにスコアを保存して、投票が行われるたびにスコアを 1 ずつ増やすことができると考えています。追加した。
どれが最良/最速ですか、および/またはこれを行う他の方法はありますか?
ユーザー「投票」テーブルと「ユーザー」テーブルを持つデータベースがあります。データベースは短時間でかなり大きくなると思うので、最も効率的な方法を使用したいと思います。
毎回「votes」テーブルから WHERE ステートメントを使用して投票数を COUNT() するか、「user」テーブルにスコアを保存して、投票が行われるたびにスコアを 1 ずつ増やすことができると考えています。追加した。
どれが最良/最速ですか、および/またはこれを行う他の方法はありますか?
あなたがそれをするための最良の方法を考えているなら。最適化とキャッシュについて多くのことを検討する必要があります。
つまり、 キャッシュされたスコアを格納するためにユーザーテーブルに列を作成しますが、スコアは別のテーブルに保持します。
スコアの変更はスコアテーブルを操作し、最新のスコア結果でユーザーのテーブルの更新をトリガーします。
これを行うと、stackoverflowが投票に使用するような、スコアデータの拡張性が得られます。
適切な構成(ほとんどの場合、デフォルト構成で十分です)では、MySQL 5.0以降のサーバーがSUM、COUNTクエリをキャッシュしているため、MySQLはその種のクエリを自動的に処理します。
ただし、古いバージョン(MySQL 4以下)を使用している場合は、COUNT(*)値をデータベースに保存することをお勧めします。これは、大きなテーブルのパフォーマンスに実際に影響を与えるためです。
編集:私が発見したベストプラクティスは、ユーザーが投票/コメントなどを追加/削除するたびにCOUNT(*)クエリを作成することです。最新のSQLサーバーはグループクエリを非常にうまく処理しているため、パフォーマンスについて気にする必要はありません。
事前計算は、しばしば非正規化する最適化の1つです。
したがって、事前に計算された列を作成し、トリガーまたはアプリケーションコードで維持するだけです。
@Bohemianが指摘したように、パフォーマンスの問題がある場合にのみ、これを行う必要があります。
これは、コストと複雑さのトレードオフです。ユーザーテーブルのカウントを維持することにより、正確さを維持するための複雑さが増し、投票の挿入/削除にコストがかかります。つまり、投票を追加するには、(少なくとも)2つのテーブルを更新する必要があります。
したがって、どの部分が最も効率的である必要があるかによって少し異なります。投票数の取得が非常に頻繁に実行される場合は、数を維持することはおそらく理にかなっています。
しかし、私の意見では、最初に単純な実装を採用し、データベースがクエリを最適化して問題にならないようにすることができると想定する方がよいでしょう。それが十分に速くないことが判明した場合は、後で事前に計算されたカウントを追加するように変更を加えます。