2017-09-06 115 views
-1

我有一些代碼從我的SQL數據庫(約200k條記錄,7列)中獲取相對較大的數據量,然後我必須對其執行更新/插入到其他表中。使用SqlDataReader處理大數據集

我最初的迭代是通過打開一個SqlDataReader並循環來完成的 - 雖然這看起來似乎在數據庫上保存了一個打開的事務,並且可能會導致某些鎖定問題,當進程運行幾個小時時。數據是通過sql存儲過程獲取的,我非常確定這是非常優化的。每個記錄的處理都相當密集。

我的僞代碼:

string sql = "EXEC StoredProc" 
sqlConn.Open(); 
SqlCommand sqlComm = new SqlCommand(sql, sqlConn); 
SqlDataReader reader = sqlComm.ExecuteReader(); 

//loop through products 
while (reader.Read())  
{ 
    // do stuff 
} 

我可以把SqlDataReader的到一個數組或列表<>抓住它「脫機」,所以DB是等待所有的代碼中解放出來之間運行幾百千次 - 是否會改善問題或使情況變得更糟,因爲內存中會保存如此之多的數據?

+0

這裏有很多事情發生,這似乎是一個非常糟糕的主意。你通過一個程序打開一個記錄集。然後你循環(無主)通過那個巨大的記錄集並插入(告訴我它不是真的)到另一個表中......以及其他一些事情。這個端到端的設計,你確定你做出了正確的決定嗎?我想你可以遍歷這個記錄集並將它推入一個數組,但是在這個運行的糟糕系統上,你的數組大小爲200k。 – JNevill

+0

我聽你的 - 基本上我需要閱讀我的原始表的每個記錄,通過一些其他的代碼運行的一些價值觀,寫那些新值到另一個表 - 我不能做到這一點的SQL裏面的代碼這個處理過程非常複雜,並且相當一部分C#代碼。我想我可以將這個過程分成更小的塊,但最終我必須處理這一切! – chilluk

+0

現在我已經看到了您對JNevill評論的回覆,我可以補充一點,您可能會從編寫CLR過程中獲得最佳結果。 –

回答

0

JNevill提出了一些重要的問題,但我現在將你的問題當作學術處理。

我可以把SqlDataReader的到一個數組或列表<>抓住它 「脫機」,所以DB是在 之間等待所有的代碼運行幾十萬次

釋放

當然可以。

會改善事情或使情況變得更糟,因爲會有很多數據保存在內存中嗎?

現在好了,取決於哪個更糟糕:只要數據讀取器鎖定您的表,或者讓您的整個數據集存儲在內存中。這兩者都不是普遍的更好或更差,它取決於它對您的業務和用戶的影響。無論你認爲哪種情況更糟糕。

如果兩者都不可接受,你總是可以選擇C選項,並讀取數據並立即將其寫入磁盤上的平面文件(使用filesystemobject),因此它不會保持sql表被鎖定,並且不會保留數據在記憶中。然後,您可以通過文件流逐行執行繁重的處理,最後從平面文件寫入數據庫。

請記住,如果你不保持在加工過程中鎖定表,更改可能會表中其他用戶所做的,當你覆蓋表與處理的數據這些更改將丟失。再次,你必須確定哪種情況更糟糕。

+0

我想如上我可以批量到更小的塊,但我仍然需要最終迭代我的原始表中的每一個記錄。我猜想使用文件系統是一種將數據從數據庫中「緩存」出來的方式 - 同時對主表中發生的其他更改無關緊要。 – chilluk