2017-06-07 27 views
1

すべてのユーザーに対して、アプリケーションはログインした回数やクイズで間違った回数などの統計を計算します。物事のこのアプリケーションはSQL Serverと.NET Entity Framework 6.1で動作します。計算された列、または統計を維持するためのトリガーによる列の更新

現在、統計はオンデマンドで計算されますが、ユーザーベースが拡大するにつれて、アプリケーションのレポート部分がさらに遅くなります。

計算された列(永続化されているか保持されていないか)を使用するか、トリガーを使用してこれらの値をユーザーに格納することについては不思議でした。

どうやってこれをやりますか?計算された列は実装が簡単かもしれませんが、テーブルからユーザーを読み込むたびに再計算されることになります。これは、今行っているよりもはるかに高速ではない可能性があります。計算された列にSQLクエリ全体を当てはめるので、列の永続化は適切なものではありません(SQL Serverは計算の更新方法をどのように推測しますか?)。 特定のアクションのトリガーは、私にとってより論理的なフィット感があるようです。

引数として、計算されたすべての統計値が他のテーブルの値のcount(*)sum(*)であり、それ以上のものはないとします。

+0

__how彼らは何度もログインしました__これは絶え間なく進化し続けていますが、クイズで間違っている__howの多くの回答は「クイズ」が完了した後は静的な数字に見えます。したがって、実際には2つの非常に異なる状況があり、おそらく異なるアプローチが必要になります。 – SMor

+0

あなたのコメントをありがとう、しかし、彼らはちょうど2つのばかげた例だった。実際には、彼らはすべて常に変化する数字です。 –

答えて

1

計算された値を格納するの場合、このビアのトリガを手動で実装するのではなく、SQL Engineで作業することをお勧めします。

したがって、それは持続されますcomputed columnおよび/またはindexed viewsです。

彼らはあなたが がで計算列が含まれる場合にのみ、私はテーブル

からユーザーを読み込むたびに再計算になるだろう

あなた SELECT(そしてあなたはそれを永続化するために選んだていませんでした) 。このため、クエリでは一般に、 select *ではなく、必要な列のみをクエリする必要があります。しかし、ORMを使用しているため、高価なカラムを含まないようにすることができない場合があります。そのため、永続性を優先するか、インデックス付きビューを使用する必要があります。そのため、読み込み専用のオブジェクトとして扱われます必要に応じて。

SQL Serverは計算を更新する必要があるとどのように推定しますか?

舞台裏で、SQL Serverは効果的にトリガー自体を実装しているため、しかし、ここのボーナスは、それらのトリガーは何百万回もテストされており、コードを書く必要はありません。議論の便宜上

、すべての計算された統計は、このような状況では、他のテーブルでcount(*)と値のsum(*)

あり、あなたが本当に計算(計算列のルートを行くことができないと仮定UDFを使用してこれをバイパスしようとするいくつかの風変わりな方法がありますが、通常はこれに対してお勧めします)、この場合はインデックス付きのビューを推奨しています。議論の便宜上

0

、すべての計算された統計が値とそれよりももっと面白い何のカウント()との和()あるとします。

レポートの操作が簡単なので、これらの統計情報のレポート表/監査ログ表をお勧めします。

基本的な前提は

SELECT 
    COUNT(*) OVER(PARTITION BY colA ORDER BY colB) as Metric1, 
    SUM(*) OVER (PARTITION BY colD ORDER BY colC) as Metric2 
FROM tblUserLog (NO LOCK) WHERE UserID =34 

主な問題は、移入する方法今であるように、すべてのレポートが

SELECT COUNT(*) FROM tblUserLog (NO LOCK) WHERE UserID=34 

またはやや複雑なクエリのように単純なクエリのバリエーションとして得ることができるということですこの表tblUserLogおよび組成はであるべきである。

作曲

テーブルのスキーマのが一般的なあるべきと数えるかに合計する列のように、すべてのレポートのニーズを満たす必要があります。

LogID (PK, auto increment) 
LogDateTimestamp 
LogType 
UserID 
MetricToSum1 
MetricToSum2 
.... 

これはむしろ正規化されたテーブルです。それを正規化することはお勧めしません。これは間違いなく、トリガーを経由して行われるべきではありません

:どのように移入する

。可能な限り最良の選択肢を見て、あなたのWebアプリケーションがうまく階層化されたアーキテクチャを持っていると仮定します。 DBテーブルに必要な詳細を挿入できるログメソッドを用意する必要があります。非同期にです。したがって、基本的にテーブルに書き込むことは、メインユーザテーブルCRUDと非同期的に発生し、レポートが必要なときは常に のオンデマンドで読み込みます。

非常に簡単な操作のために、Userのようなメインエンティティテーブルのビューを実装することをお勧めします。このソートの例は、adminレポートのアクティブユーザー数を返すビューです。

関連する問題