8

人々が好きな色にプラス (+1) またはマイナス (-1) の投票をするサイトを考えてみましょう。私には 2 つのテーブルがあります。

1 つは人々が投票できるすべての色を一覧表示し、2 番目の表は各個人の投票が記録され、その色は何色で、+1 か -1 かを示しています。

特定の色の集計投票を取得することに関しては、色テーブルに集計スコアを含め、人が投票するときに挿入ステートメントと更新ステートメントがあると効率的でしょうか。

INSERT INTO votes (colour,vote) VALUES (red,-1);
UPDATE colours SET score=score-1 WHERE colour='red';

SELECT score FROM colours WHERE colour='red';

または、投票が行われたときに INSERT ステートメントを 1 つだけにして、スコアを取得する方が効率的でしょうか。

SELECT SUM(vote) AS score FROM votes WHERE colour='red';

投票数が非常に少ない場合はオプション#2が最適ですが、投票テーブルが非常に大きい場合はオプション#1の方が良くなりますか?

テーブルのサイズなどに応じて、特定の SQL クエリに一種のランキングを与えるために使用できるツールはありますか?

4

4 に答える 4

4

個人的には、集計スコアを表示したい場合 (スコアを頻繁に表示したいと思うと思います)、投票テーブルの行数が増えると、集計SUMクエリの時間が長くなることがわかります。より長く、あまりうまくスケーリングしません。

さらに、スコアが 100 以上の色のみを表示するクエリの実装を計画している場合は、集計を使用すると、クエリがより簡単で高速になります。

スコア列を使用するもう 1 つの利点は、将来、テーブルを一掃したいvotes場合 (テーブルが大きくなりすぎた場合など) に、カラー スコアを失うことなくそれを実行できることです。

これは時期尚早の最適化ではないと思います。これはスケールを念頭に置いてシステムを設計していると思います。したがって、私が行うことは、予想される 1 分あたりの現実的な数の投票、色、およびクエリのサンプル データセットを作成することです。いくつかのパフォーマンス テストを実行して、より良いアプローチを評価してください。問題が発生し始めたときに修正するよりも、今すぐ正しいアプローチを選択する方が簡単です (より安く読むことができます)。

于 2013-03-08T10:22:55.450 に答える
1

2 つのクエリのパフォーマンスの違いはわずかです。保持したい情報に基づいて構造を決定する必要があります。

集計スコアのみが必要な場合は、次を使用します

UPDATE colours SET score=score-1 WHERE colour='red';

coloursテーブルには数行しかないため、これは非常に高速です。

一方、各ユーザーの投票を保存する理由がある場合もあります (2 回投票しないようにするなど)。その場合、投票ごとに行を挿入します。

INSERT INTO votes (colour,vote,user_id) VALUES (red,-1);

ただし、高速になると考えているからといって、不要な行の構造を作成しないでください。

于 2013-03-08T10:10:29.140 に答える
0

このタイプの最適化の要点は、何を最適化するかです。合計を保存すると、挿入/削除/更新に時間がかかります。合計を計算すると、データに対するクエリのパフォーマンスに影響します。

データの削除または更新を行っている場合は、合計を事前に計算するという愚かさがすぐにわかります。データをこのように変更する場合は、1つだけを変更すると思われる場合は、複数のレコードを変更する必要があります。

ただし、構造にはインサートしかないように見えます。ちなみに、すべての変更が表示されるため、設計上の選択として適しています。この場合、問題は、各挿入でオーバーヘッドを取得するか、「レポート」側でオーバーヘッドを取得するかです。質問は簡単な場合もあります。

合計を確認するたびに1000票がある場合は、その場で合計を計算します。投票ごとに1000の合計がある場合、合計を保存する方がより効率的なアプローチのように見えます。

私の推測では、作業負荷は両極端の間のどこかにあります。私の自然なバイアスは、生成されたデータを保存してから、要約とレポート用の追加のテーブルを用意することです。次の2つのアプローチのいずれかをお勧めします。

(1)トランザクションデータのみを保持し、その場で合計を計算します。合計ができるだけ効率的になるように、テーブルにインデックスを配置します。

(2)トランザクションのみを1つのテーブルに保持し、合計を別のテーブルで計算します(トリガーまたはストアドプロシージャのいずれかを使用)。これにより、ほとんどの目的に必要な最新の値が得られます。挿入は、各レコードに合計を格納するよりも効率的である必要があります(ユーザーレベルのテーブルは投票レベルのテーブルよりも小さいため)。

投票記録の合計を計算するというあなたの提案は、通常、私が検討するオプションではありません。増分投票の履歴が必要な場合に望ましいでしょう。ただし、履歴を確認している場合はsum、アプリケーション層で計算を実行するか、合計を計算することも実行可能な代替手段になります。

于 2013-03-08T12:07:41.113 に答える
0

時期尚早に最適化していますか、それともこれは本当の問題ですか?

最初のアプローチはより高速かもしれませんが、最適化のためにドメイン モデルを変更します。自分が何をしているのか、そしてそれがもたらす不利益を知っていれば問題ありません (たとえば、投票を処理するすべての場所で 2 つのテーブルを更新する必要があり、非同期化につながる可能性があります)。

ただし、他のオプションを検討することもできます。たとえば、色の数がそれほど多くない場合は、評価のキャッシュを構築できます。これにより、単純なモデル、プレーンな評価メカニズムが維持され、必要な速度が提供されますが、メモリがいくらか減ります ;)

于 2013-03-08T10:15:04.030 に答える