2013-03-05 36 views
1

我有一個代碼提交大量的數據行到數據庫(sql 2008 R2)使用c#應用程序的問題。使用c寫入大量或行到mssql數據庫#

我現在正在做的是創建一個相當大的XML文件(大約30Mb),它將包含大約40,000行,應該插入到數據庫中。

從這個xml文檔,我傳遞給數據庫作爲變量我有一個存儲過程,將讀取數據並做適當的插入或更新。

僞C#代碼:

String xml = xmlWriter.ToString(); 
SqlCommand cmd = new SqlCommand("sp_CommitData", connection) 
cmd.Variables.AddWithValue("@xml", xml); 
SqlDataReader reader = cmd.ExecuteReader(); 
while(reader.Read()) 
{ 
/* Read return data */ 
} 

僞TSQL代碼:

INSERT INTO DataTable 
xmldata.value('@uID','[uniqueidentifier]') AS [uID] 
FROM< 
@xml.nodes('/data/m/r') [xmldata](xmldata) 

這種方法工作得很好,我過去,但現在的數據似乎是廣闊爲了工作的方式......只需提交數據就需要3分多鐘,而這只是很長一段時間。 :(

這一定是一個很常見的問題,你們在類似的情況下如何做? 你有什麼關於如何用c#提交大量數據的好指針,解決方案必須是線程安全的所以我不那麼花哨有關bcp或類似的方法。

親切的問候 德魯

+0

您使用SQL Server 2008嗎?表值參數應該有相當大的幫助。 – ChaosPandion 2013-03-05 13:01:56

+1

如果你插入了大量的數據,我建議你看看'SqlBulkCopy'類 – Kane 2013-03-05 13:03:17

+0

一個事務中的所有40.000行?如果是這樣,他們必須在一個交易? – mortb 2013-03-05 13:03:24

回答

5

要做到這一點是通過使用SqlBulkCopy最快的方式,將使用SQL的批量加載功能。

XML方法的問題是你冷杉st必須從你的行集/ IEnumerable(你有什麼需要準確地開始?)轉換爲XML,然後通過網絡推送它。 XML是一種非常臃腫的格式,在你提到很多行的時候這一點很重要。

大容量複製方法可讓您逐行進行流式處理,而無需實現整個過程(進入內存或磁盤),從而減少內存佔用。

如果數據量非常大,您可能需要首先將其加載到臨時表(所以沒有真正表的事務)和插入(或Merge)到真實事物中。

你對線程安全意味着什麼?如果您希望此操作不阻止客戶端,則可以輕鬆地在後臺線程上啓動它。沒有任何外部流程或任何您需要開始執行此操作的流程,它在流程中運行。

+0

對SqlBulkCopy的評論是,您需要導入到堆(沒有集羣鍵的表)並使用表鎖來優化性能。請參閱[MSDN](http://msdn.microsoft.com/zh-cn/library/ms186341(v = sql.105).aspx)和[本討論主題](http://social.msdn.microsoft.com/Forums/en-US/sqldataaccess/thread/932cd26c-53fc-49c0-b082-e7f5f05a9801)以獲取更多信息。 – PHeiberg 2013-03-05 13:15:10

+0

是的,如果數據庫很忙,我會先把它放在臨時表中以防止鎖定。 – gjvdkamp 2013-03-05 13:17:52

+0

線程安全的是,它會對這個服務發出很多併發調用,並將保存發送到數據庫。這些保存中的任何一個都不應該阻止對其他呼叫的訪問,而是允許該服務同時執行呼叫。 – user2135792 2013-03-06 12:50:22

0

感謝您對此問題的輸入。我已經開始查看SqlBulkCopy,但在一段時間後停滯了,因爲我需要一個存儲過程來執行接近邏輯的數據。
鑑於我可能會有許多併發線程來保存數據的服務,我不能用數據填充臨時表,以後再從中讀取數據。

然後我把注意力轉向表值參數,並在那裏找到我的答案。我有點驚訝我以前沒有嘗試過,因爲它發揮得很好。在表現數字中,節省從大約45秒到不到5秒!

謝謝你指出我在這個方向。