C#的資料庫應用如何解決記憶體消耗太大的問題呢?

來源:互聯網
上載者:User
文章目錄
  • 1. 最開始用最簡單的DataAdapter.Fill(DataTable)的辦法。
  • 2. 我嘗試用DataReader讀入資料,然後寫進dtDest
  • 3. 純SQL語句。不用DataTable
  • 4. 不輸出到資料庫,以CSV輸出到文字檔
  • 5.匯出到XML
本來是個文章,但是問的問題沒有得到實際的答案。所以乾脆放到Blog上來好了,當作長期的一個題目。這樣如果有人看的話,也許能夠給我一些線索。

我用C#做資料庫應用的時候,經常遇到的一個問題就是記憶體消耗特別大。這種情
況在作大資料量的資料庫匯入匯出的時候更為明顯。
說一個常見的資料庫匯入匯出的Case, 大家看看比較合理的辦法是什麼:

環境:
有一個資料庫SRC, 裡面有500萬條記錄。有A, B, C三個欄位。資料庫的大小去
掉水分後,大約500MB的數量級。這個作為來源資料庫。
資料庫DEST是目標資料庫,裡面有AA, BB, CC, DD, EE, FF等5個欄位。

其中,AA, BB, CC的值,是根據SRC.A和B的值計算得來的。而且過程複雜,所以
不適合使用預存程序實現。並且AA, BB, CC不是單獨得出,而是同時以SRC.A和
SRC.B得出的(當然,運算三遍可以分別取到各值,但顯然運算量就大了3倍)。

目的:
將SRC中的所有資料經過變換,匯入到資料庫DEST中。

我所嘗試過的方法:

1. 最開始用最簡單的DataAdapter.Fill(DataTable)的辦法。

然後
foreach(DataRow rowsrc in dtSrc){
    DataRow row = dtDest.NewRow();
    ....
    dtDest.Rows.Add(row);
}
daDest.Update(dtDest);
dtDest.AcceptChanges();

這明顯不是處理大資料量遷移的辦法。
最明顯的問題是記憶體消耗極大。500MB的資料庫表變成DataSet中的DataTable,
體積括大了很多。再加上dtDest中的拷貝,還有daDest.Update所佔用的資源,
很容易就超過了2GB的應用程式記憶體位址空間,而報錯退出了。

2. 我嘗試用DataReader讀入資料,然後寫進dtDest

using( ... reader = ...){
    while(reader.Read()){
        DataRow row = dtDest.NewRow();
        ....
        dtDest.Rows.Add(row);
    }
}
daDest.Update(dtDest);
dtDest.AcceptChanges();
記憶體佔用少了很多,因為SRC讀入DataReader的資料,似乎會因為之後不用了,
而有所釋放。但是已經進入dtDest的資料沒有必要儲存在記憶體中的道理。可是又
沒有辦法。即使daDest.Update和dtDest.AcceptChanges()後,它依然佔用這內
存。因此將daDest.Update和dtDest.AcceptChanges()放入迴圈內,並不能對內
存使用有所改善。

3. 純SQL語句。不用DataTable

用SqlCommand.ExecuteNonQuery()的來執行"Insert Into ..."的SQL語句。這樣
作後,發現記憶體佔用大大降低了。起到了想達到的“管道”的效果。可是最之而來
的確實更嚴重的問題。這樣做的磁碟空間佔用極大。資料庫會產生大量的日誌,
和廢棄空間。以Access為例,程式運行一段時間後,就超過了2GB最大檔案的限
制。當執行“壓縮和恢複資料庫”後,只有100MB左右。可見產生的資料垃圾多
大。當然,採用SQL Server會沒有2GB的限制,但是這麼大量的日誌和廢棄空
間,絕對不是一個適合的結果。而且,如果安這種比例,一個500MB的資料庫,
將佔用超過10GB的儲存空間,這是一個太大的浪費了。當然事後可以壓縮,但是
處理過程中的空間浪費不容忽視。

4. 不輸出到資料庫,以CSV輸出到文字檔

這是個辦法,至少一來不佔用什麼記憶體,二來,也沒有浪費硬碟空間。但是麻煩
的是,丟失了最重要的類型資訊。對於字串和數字還好說,最多就是字串沒
有了長度,數字沒有了精度,但都還能夠儲存下來。比較麻煩的是有些複雜類
型,比如IMAGE, Binary,和GUID等,這種位元組流形式的類型是沒有辦法報存在
CSV中的。

5.匯出到XML

當然用XML好一些,但是其Binary儲存的Parse也是很耗費資源的,而且,用XML
如何才能匯入到資料庫中呢?用C#就又回到老路上來了。SQL Server支援XML,
但是其他的資料庫呢?例如Access? 畢竟不是所有人都買的起SQL Server或者所
有場合都適於使用SQL Server的。

對於這個問題大家有什麼好辦法嗎?我覺得操作大一點的資料庫的時候,記憶體占
用是個很明顯的問題。也許有很簡單的方法我沒有考慮到而走了很多彎路。謝謝了。

Dancefire
---
CCNA
http://www.dancefires.com/
http://blog.csdn.net/dancefire/
MSN: Dancefire@263.net
I am interested in Operating System, Embedded System and Network Security.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.