2010-07-05 74 views
3

我們有一個應用程序,它將實時數據插入到數據庫中。它每天在線4.5小時。我們在17個表中以秒爲單位插入數據。在任何時候,用戶可以查詢最新的第二數據的任何表,並在歷史上的一些記錄......從內存中插入和查詢數據的最佳實踐

處理的飼料和插入使用C#控制檯應用程序後...

處理用戶請求是通過WCF服務完成...

我們發現插入是我們的瓶頸;大部分時間都在那裏。我們投入了大量時間試圖調整表和indecies但結果不令人滿意

假設我們有足夠的內存,最好的做法是將數據插入到內存而不是有數據庫。目前我們正在使用每秒更新和插入的數據表 我們的一位同事在提要處理程序和WCF用戶請求處理程序之間建議了另一個WCF服務,而不是數據庫。 WCF中間層應該是基於TCP的,它將數據保存在自己的內存中。有人可能會說飼料處理程序可能會處理用戶請求,而不是在兩個進程之間有一箇中間層,但我們希望分離事物,所以如果飼料處理程序崩潰,我們仍然能夠向用戶提供當前記錄

我們時間有限,我們希望在短時間內將所有內容都移到內存中。在2個進程中間有一個WCF是不好的事情?我知道這些請求會增加一些開銷,但所有這3個進程(feed-handler,內存數據庫(WCF),用戶請求處理程序(WCF))都將位於同一臺計算機上,帶寬不會那麼大的問題。

請幫助!您正在使用什麼樣的數據庫

+0

確實很好的問題。 – Kangkan 2010-07-05 10:13:46

回答

2

我會研究創建數據緩存(這樣您還可以減少數據庫選擇),並在緩存中的數據寫入數據庫後使數據無效。這樣,您可以批量調用更大的插入,而不是更小的插入,但將數據保存在內存中,以便讀者可以讀取它。實際上,如果您知道數據何時過時,可以避免完全讀取數據庫並將其僅用作後備存儲 - 這樣,數據庫性能只會影響緩存的大小。

使緩存中的數據無效將基於它是寫入數據庫還是已經過時,而不是先到達最後

緩存層不需要很複雜,但它應該是多線程來託管數據並將其保存在後臺。該層將位於WCF服務的後面,連接媒介和WCF服務應該改進以包含控制檯應用程序的邏輯+批處理想法。然後,控制檯應用程序可以連接到WCF並在其上投擲結果。

更新:唯一可以說的是投資一個分析器,看看你是否在被屏蔽的代碼中引入任何性能問題。另外,分析您的數據庫。你提到你需要快速插入和選擇 - 不幸的是,它們通常會互相抵消......

+0

感謝您的答案。數據並沒有真正陳舊,因爲每個記錄都可能隨時被選中(用戶可以指定他/她想要的第二個「記錄」)。你的解決方案仍然建議插入到數據庫中,儘管創建一個緩存的頻率較低,但是我不知道我們是否仍然要從數據庫中選擇(如果數據不在緩存中,因爲歷史數據的選擇是完全隨機的)一張巨大的桌子被插入,是不是會造成選擇超時?我們不能把所有東西都堆放在內存中嗎? – mustafabar 2010-07-05 10:44:26

+1

這真的取決於 - 每4.5秒插入一次可能會產生大量數據?你的問題是插入性能 - 這可以通過其他方式解決。你可以做的是刪除所有的索引,從而爲插入性能定製表併爲這些選擇招致成本,也許使用選擇高速緩存來保存更多的內存。 – 2010-07-05 10:51:52

+1

當然,內存是一種可行的方式,但內存也是不穩定的 - 停電並且全部消失。 – 2010-07-05 11:07:26

0

?MySQL有一個存儲引擎MEMORY這似乎要適合這樣的事情。

+0

我們正在使用SQL數據庫。 Microsoft SQL server 2008 – mustafabar 2010-07-05 10:16:07

0

您使用的數據表與DataAdapter?如果是這樣,我建議你完全刪除它們,直接使用DBCommand插入你的記錄,當用戶請求報告,使用DataReader讀取數據,或者使用DataTable.Load(IDataReader)填充DataTable對象時

內存中的故障數據存在發生崩潰或電源故障時丟失數據的風險。

+0

我們創建一個SQLTransaction連接並使用它通過使用SQLBulkCopy在DataTable中循環來插入它。我們需要交易來扭轉可能的崩潰的影響 – mustafabar 2010-07-05 10:50:53