2017-06-07 73 views
1

對於每一個用戶,我們的應用程序計算的一些統計數據,就像他們在多少次登陸或用了多少的答案錯了在智力競賽中,...它可以是各種東西的。該應用程序的SQL Server和.NET實體框架6.1計算列,或觸發更新列,以保持統計

上現在運行的統計數據是按需計算,但隨着用戶羣的擴大,這使得應用程序的報告部分永遠慢。

我們想知道或者使用計算列(無論是持久或不持久)或使用觸發器來將這些值存儲與用戶。

你會怎麼做呢?在我看來,計算列可能更容易實現,但每當我從表中讀取用戶時,它們都會重新計算,這可能不會比我們現在所做的更快。由於我們將整個SQL查詢放入計算列中,因此堅持列似乎並不合適(SQL Server如何推斷它應更新計算?)。 某些行爲的觸發似乎對我來說更符合邏輯。

爲了討論的方便,假設所有的計算統計count(*)和其他表中,沒有什麼比這更有趣的值sum(*)

+0

__他們多次登錄___:這是一個不斷演變的數字,而__如果他們在測驗中出錯的答案很多,似乎是「測驗」完成後的一個靜態數字。所以你真的有兩種不同的情況,可能需要不同的方法。 – SMor

+0

嘿,謝謝你的評論,但他們只是兩個愚蠢的例子。事實上,他們都在不斷變化的數字。 –

回答

1

如果你的來存儲計算值,寧願讓SQL引擎爲你工作,而不是手動實現這個通過觸發器。

所以,這將持續computed column和/或indexed views

,他們會得到重新計算每次我從表

讀取了用戶的時間只有當你包括計算列在您的SELECT(你也沒有選擇了它要堅持) 。這就是爲什麼查詢通常只需要查詢所需列的原因,而不是select *。但是,由於您使用的是ORM,你可能不能夠告訴它不包括昂貴列 - 這就是爲什麼你應該更喜歡持久性或使用索引視圖 - 因此,它的作爲,你只加載一個單獨的物體進行處理需要的時候。

如何將SQL Server的推斷,它應該更新計算?

因爲幕後,SQL服務器有效地實現了觸發本身。但是,這裏的獎金是,這些觸發器已經過數百萬次測試,並且是您不必編寫的代碼。

爲了討論的方便,假設所有的計算統計count(*)和價值觀的sum(*)其他表

在這種情況下,你真的不能去計算列路線(計算列只有真的應該參考自己的自己行自己的表。有一些古怪的方式,試圖繞過此使用UDF的,但我通常會建議反對),所以在這種情況下,我肯定會被建議索引視圖。

0

爲了討論的方便,假設所有的計算統計值,沒有什麼比這更有趣的計數()和sum()。

由於您的報告操作非常簡單,我建議您爲這些統計信息報告表/審計日誌表。

基本前提是所有的報告可以作爲一個簡單的查詢像

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

的變化或類似

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 

主要問題稍微複雜的查詢來獲得現在如何填充此表tblUserLog應該是什麼組成

組成

的表的模式應該是通用的,並且必須滿足像列的所有報表需要指望或總結上。說一句就行了

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

這是比較不規範的表;我不會推薦標準化它。

如何填充:

這絕對不應該被通過觸發器實現。尋找最佳可行方案,並假設您的Web應用程序具有良好的分層架構;你應該有一個日誌方法,可以插入到DB表中必要的細節異步。所以基本上在桌上寫字與主要用戶表格CRUD異步發生,並在需要報告時按需閱讀 。

對於一個非常簡單的操作,我建議你簡單地實現一個像主要實體表一樣的視圖。這種排序的例子是一個視圖,它返回說明管理員報告活動用戶的數量。