2

SOに非常によく似たプロジェクトに取り組み始めました。Questions ans Answersを含む多くのテーブルを持つアプリ用のデータベース ( Code First EF-5 Sql server 2012) を作成しました。これらの両方のテーブルの間には 1 対多の関係があります ( 1の質問に複数の回答を含めることができます)。SOと同様に、質問リストビューに各質問の回答数も表示したいと思います。

明らかなアプローチは ( Answers と Questions が 1 対多の関係を持っている場合、各 question エンティティには Answers オブジェクトの List がある場合)、簡単なステートメントを書くことができます:

   question.Answers.Count;

しかし、このクエリにはパフォーマンス上の疑問があります。最初に、これを行うことにした方法を説明します(データベースの経験があまりないので、間違ったパスにいる場合は修正してください

AnswerCount質問の回答がユーザーによって挿入または削除されるたびに更新される質問テーブル名に追加の列を作成しました。このために、回答テーブルの挿入または削除イベントで実行されるSQLトリガーを作成しました。トリガーは次のとおりです。

Create TRIGGER [dbo].[trg_Answer_INSERT_Delete]
ON [dbo].[Answer] 
AFTER INSERT, DELETE 
AS BEGIN
   DECLARE @id as int = 0,
           @count as int = 0;

   SELECT TOP 1 @id = QuestionId FROM inserted; 

   IF @id = 0
    BEGIN
    SELECT TOP 1 @id = QuestionId FROM deleted; 
    END

   SELECT @count = count(*) FROM Answer where QuestionId = @id; 

   UPDATE Question
   SET AnswerCount = @count
   WHERE Id = @id;         
END

表示するたびにナビゲーション プロパティ(回答)で Count 関数を呼び出すのではなく、列にカウントを保存し、カウントを表示するたびに列の値にアクセスするのは効率的ではないため、このすべてのオーバーヘッドを実行しています。質問の答えは??

誰でもこのシナリオに詳細な光を当てることができますか?

4

2 に答える 2

0

パフォーマンスの向上を期待して、データベースを非正規化することに決めたようです。これによりパフォーマンスが向上することをご存知ですか?プロファイリングを行ったことはありますか?そうでない場合は、最初に正規化してから、実際にパフォーマンスの問題がある場合にのみ、スキーマをリファクタリングしてカウントを保存することを検討します。SOや他のサイトが何をしているのかはわかりませんが、この道を進む前にパフォーマンスの向上を確認したいと思います. おそらく他の誰かが知っていて、良い答えを与えるでしょう。

質問ごとに回答コレクションを取得する必要があるため、パフォーマンスが低下すると考えている場合は、そうではありません。匿名型 (または、質問と answerCount のペアを保持する実際の型) を返す Linq to Entity クエリをいつでも作成できます。

var query = context.questions.GroupJoin(context.answers,
q => q.QuestionId,
a => a.QuestionId,
(q, aGroup) => new
{
Question = q,
AnswerCount = aGroup.Count()
});

上記は、回答を具体化することなく、質問と回答数を含む匿名型を返します。必要に応じて、質問のタイトルと回答数の匿名型のみを返すようにさらに調整できます。

于 2013-05-01T11:36:51.537 に答える
0

AnswerCount 列を Questions テーブルに追加すると (非正規化)、クエリのパフォーマンスが向上することは間違いありません。トレードオフは、トリガーSELECT @count = count(*) FROM Answer where QuestionId = @id;. この選択を発行する代わりに、回答の挿入か回答の削除かに応じて、質問の AnswerCount 列の値を単純に増減できます。PS AnswerCount のデフォルト値を 0 にします。

于 2013-05-01T12:41:43.173 に答える